AutoFixture AutoMoq partially covers class constructor - c#

I am using AutoFixture AutoMoq and it's greatly simplifies the mock for all interface used in class and initialize it.
Though I noticed the constructor code is partially covered, can we modify AutoMoqDataAttribute so that constructor ArgumentNullException can also be covered?
public class ServiceTest
{
[Theory, AutoMoqData]
public async Task Do_Test_For_DoMethod(Service sut)
{
await sut.DoMethod();
}
}
AutoMoqData attribute class,
public class AutoMoqDataAttribute : AutoDataAttribute
{
public AutoMoqDataAttribute()
: base(() => new Fixture().Customize(new AutoMoqCustomization()))
{
}
}
Service class code,
public class Service
{
private readonly IServiceClient _serviceClient;
private readonly ILogger<Service> _logger;
public Service(IServiceClient serviceClient, ILogger<Service> logger)
{
_serviceClient = serviceClient ?? throw new ArgumentNullException(nameof(serviceClient));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public async Task DoMethod()
{
await _serviceClient.Do();
}
}

It is not the responsibility of the AutoDataAttribute to know how to cover your code. It is the developers responsibility to express intent and explicitly cover the scenario.
In your case the uncovered branches are the null guards. Luckily AutoFixture provides a library just for that, AutoFixture.Idioms.
This library provides idiomatic assertions, that encapsulate most basic test scenarios like null guards, property setters, equality members and so on.
Using this library you can write a test like the following.
[Theory, AutoMockData]
void CheckGuards(GuardClauseAssertion assertion)
{
assertion.Verify(typeof(Service));
}
This should cover all the parameters of all the constructors, and the nice part is that it uses your customization, so it will generate valid data when attempting to instantiate your object.

Related

Mock async generic method from base class

I've classes similar to this:
public class Class1
{
private readonly IClient _client;
public Class1(Configuration config, CacheManager cacheManager)
{
_client = new Client(config, cacheManager);
}
protected async Task<T> PostAndDeserialize<T>(string param1, object param2)
{
var result = await _client.PostSomething(param1, param2);
return JsonConvert.DeserializeObject<T>(await result.Content.ReadAsStringAsync());
}
}
public class Class2 : Class1
{
public Class2(Configuration config, CacheManager cacheManager) : base(config, cacheManager)
{
}
public async Task<Response> CreateSomething(Request request)
{
//do something
var result = PostAndDeserialize<Result>("test", test);
return new Response { Id = result.Id };
}
}
I need to write unit test for Class2, CreateSomething method - how do I mock PostAndDeserialize method ? I've tried and find a way to mock protected generic class from base class but I couldn't find any help with it :( Or maybe it should be done in some other way ?(I'm new to unit test). Any help is appreciated.
I've tried using Protected() and calling method by it's name but as it's generic method it didn't work.
Your options are:
Rewrite the code so it is testable. This can be done by making the method virtual or by using composition instead of inheritance and program to an interface instead of an implementation.
Purchase Visual Studio Enterprise which includes Microsoft Fakes. Or some other third-party solution.

FakeItEasy: how to unit test abstract class

I want to mock abstract class public method to returns different values. Is it doable using fakeiteasy?
public class Worker: IInterface
{
private readonly ILogger _logger;
provate readonly IServiceProvider _serviceProvider;
public Worker(ILogger logger, IServiceProvider provider)
{
_logger = logger;
_serviceProvider = provider;
}
public Handler(Order order)
{
var service = _serviceProvier.GetService(order.Properties.Type);
service.DoTaskAsync(...);
}
}
public abstract class ServiceBases
{
public async Task DoTaskAsync(...);
}
[Fact]
public async Task WorkerHandler_Return_Success()
{
// how to mock ServiceBases.DoTaskAsync to returns null or throw exception ?
}
This is complicated because you've got two things to figure out:
How to create a mock of your abstract class
How to set up your IServiceProvider to return an instance of the class that inherits from the abstract class.
Let's start with mocking the abstract class. The easiest way to do that is to create a class that implements the abstract class. You could do this:
public class FakeServiceBases : ServiceBases
{
public int NumberOfTimesCalled { get; private set; }
public override async Task DoTaskAsync()
{
NumberOfTimesCalled++;
}
}
Presumable you're mocking this so that you can make sure the class that depends on this calls DoTaskAsync(). If you create an instance of this fake class then when Handler calls it, it will increment the value. When the test runs you can check that the value has been incremented.
Or maybe you want to make sure that the expected arguments were passed. I don't know what the arguments are, but when DoTaskAsync() is called you can add the arguments to a list instead of incrementing a number, like this:
public class FakeServiceBases : ServiceBases
{
public List<SomeArgumentType> CallsToDoAsync { get; } = new List<SomeArgumentType>();
public override async Task DoTaskAsync(SomeArgumentType someArgument)
{
CallsToDoAsync.Add(someArgument);
}
}
Same thing. After calling your Handler method you can inspect the arguments that were passed to service.DoTaskAsync by looking at what's in the CallsToDoAsync list.
That takes care of mocking ServiceBases. The other step is getting your IServiceProvider to always return a FakeServiceBase regardless of the type passed to it.
That you can do with FakeItEasy.
var fakeServiceBase = new FakeServiceBases();
var serviceProvider = A.Fake<IServiceProvider>();
A.CallTo(() => serviceProvider.GetService(A<Type>.Ignored)).Returns(fakeServiceBase);
var testSubject = new Worker(NullLogger.Instance, serviceProvider);
This creates a faked IServiceProvider. Whenever GetService is called, regardless of the type passed to it, it will return the instance of FakeServiceBases that you created. After calling methods on the Worker you can inspect fakeServiceBase to make sure methods were called on it like you expected.
We can make this class easier to test by removing the dependency on IServiceProvider.
Let's change Worker to look like this:
public class Worker
{
private readonly ILogger _logger;
private readonly Func<Type, ServiceBases> _getServicesBases;
public Worker(ILogger logger, Func<Type, ServiceBases> getServicesBases)
{
_logger = logger;
_getServicesBases = getServicesBases;
}
public async Task Handler(Order order)
{
// Calls the function - passes a Type and gets a ServiceBases
var service = _getServicesBases(order.Properties.Type);
service.DoTaskAsync(...);
}
}
Now it doesn't depend on IServiceProvider. It depends on a Func<Type, ServiceBases>. In other words, it depends on a function that will take a Type and return an object that implements ServicesBases.
When you're registering your types in your Startup you can do this:
services.AddSingleton<Func<Type, ServiceBases>>(serviceProvider =>
new Func<Type, ServiceBases>(type => (ServiceBases)serviceProvider.GetService(type)));
So at runtime the function will actually resolve the type from the IServiceProvider.
But now that your class depends on a function, the mock is even simpler. You don't need to mock an IServiceProvider. Instead, you provide a "real" function that returns your FakeServiceBases:
var fakeServiceBase = new FakeServiceBases();
Func<Type, ServiceBases> getServiceBases = type => fakeServiceBase;
var testSubject = new Worker(NullLogger.Instance, getServiceBases);

Instantiate another class in sealed class

What is the recommended way to instantiate another class inside a sealed class:
public sealed class AvayaService
{
private static Lazy<AvayaService> lazy =
new Lazy<AvayaService>(() => new AvayaService());
public static AvayaService AvayaServiceInstance
{
get
{
if (!lazy.IsValueCreated)
lazy = new Lazy<AvayaService>(() => new AvayaService());
return lazy.Value;
}
}
private AvayaService()
{
}
public static Response GetResponse(Request request)
{
var _repository = new Repository(); // what is the best way to get the instance here
}
}
public class Repository : IRepository
{
...
}
I am trying to learn sealed class and lazy instantiation however I am pondering over what should be the recommended way to instantiate another class in a sealed class?
There's no "recommendations" in this area. If you've read recommendations, read again, most probably it was just an exercise. It gives you an idea, but using this idea in a real project is up to you. Sometimes those exercises demonstrate an opposite approaches. Sometimes the repository owner will dictate the style which is against of any rules you've read before, and it's totally fine.
Here's another instantiation exercise which I think is helpful to try: to never instantiate anything except value objects. Delegate instantiation to a container. Avoid singleton pattern, but register your service as a singleton in your container. In this way your code will look like:
public sealed class AvayaService
{
private readonly IRepository _repository;
public AvayaService(IRepository repository)
{
if(repository == null)
throw new ArgumentNullException();
_repository = repository;
}
public static Response GetResponse(Request request)
{
// use _repository
}
}

Resolving generic Decorators with Simple Injector

I am trying to build out a structure where I have a base IValidator<> interface that will be generated for our system based on some metadata. We want to give future developers the flexibility to 1) Regenerate the concrete implementations of IValidator<> if need be without disturbing any hand-written code and 2) Add decorators to IValidator<> to be able to extend the functionality without disturbing the auto-generated code.
I would like to have some way to resolve the generic decorators at runtime using the RegisterDecorator method of Simple Injector so our dev team does not need to go and update the composition root every time we add a decorator.
Here are some example classes/interfaces
public interface IValidator<T> where T : class
{
void Validate(T entity);
}
public class ClientValidator : IValidator<Client>
{
public void Validate(Client entity)
{
//Auto-generated
}
}
public class UserValidator : IValidator<User>
{
public void Validate(User entity)
{
//Auto-generated
}
}
public class ClientValidatorDecorator : IValidator<Client>
{
private readonly IValidator<Client> clientValidator;
public ClientValidatorDecorator(IValidator<Client> clientValidator)
{
this.clientValidator = clientValidator;
}
public void Validate(Client entity)
{
//New rules
this.clientValidator.Validate(entity);
}
}
public class UserValidatorDecorator : IValidator<User>
{
private readonly IValidator<User> userValidator;
public UserValidatorDecorator(IValidator<User> userValidator)
{
this.userValidator = userValidator;
}
public void Validate(User entity)
{
//New rules
this.userValidator.Validate(entity);
}
}
public class ValidationContext
{
private readonly IValidator<Client> client;
private readonly IValidator<User> user;
public ValidationContext(IValidator<Client> client, IValidator<User> user)
{
this.client = client;
this.user = user;
}
}
We I am trying to do something like so:
public void RegisterServices(Container container)
{
container.Register(typeof(IValidator<>), AssemblyManifest.GetAssemblies());
container.RegisterDecorator(typeof(IValidator<>), GetType, Lifestyle.Transient, UseType);
}
private static Type GetType(DecoratorPredicateContext ctx)
{
//Return appropriate Decorator
}
private static bool UseType(DecoratorPredicateContext ctx)
{
//Predicate
}
Unfortunately, unless I resolve a concrete type RegisterDecorator throws an error, so resolving another generic seems out. I am not sure how to proceed. Is there a way to do something like this? Is there a better way to get the intended functionality without decorators? We were thinking partial classes, but that has its own set of issues.
Any help will be appreciated!
Rather than plugging in decorators you could use a Composite Validator to enable the addition of IValidator<> implementations as required. This solution would allow the code to contain multiple IValidator<>'s for the same type.
Internally your code will still be able to depend on a single IValidator<T> which would resolve to the CompositeValidator that would call zero or more validators depending on what has been registered in the container at runtime.
The composite validator:
public class CompositeValidator<T> : IValidator<T>
{
public readonly IEnumerable<IValidator<T>> validators;
public CompositeValidator(IEnumerable<IValidator<T>> validators)
{
this.validators = validators;
}
public void Validate(T item)
{
foreach(var validator in this.validators)
{
validator.Validate(item);
}
}
}
The container is configured like this:
var assemblies = new[] { typeof(IValidator<>).Assembly };
var container = new Container();
container.RegisterCollection(typeof(IValidator<>), assemblies);
container.Register(typeof(IValidator<>), typeof(CompositeValidator<>));
where the assemblies variable contains all the assemblies you want to search for validators.
When you resolve IValidator<User> using container.GetInstance<IValidator<User>>() or through constructor injection you get back CompositeValidator<User> which internally references any and all IValidator<User>'s.
The way to get decorators of a type using batch registration is by calling the GetTypesToRegister method overload that accepts a TypesToRegisterOptions object. This way you can instruct SI to return decorators as well.
container.Register(typeof(IValidator<>), assemblies);
var t1 = container.GetTypesToRegister(typeof(IValidator<>), assemblies);
var t2 = container.GetTypesToRegister(typeof(IValidator<>), assemblies,
new TypesToRegisterOptions { IncludeDecorators = true });
foreach (Type t in t2.Except(t1)) {
container.RegisterDecorator(typeof(IValidator<>), t);
}
Do note that I do not suggest using this code. #qujck's answer addresses the design issue you have with your code, and his solutions therefore brings you to a much better place.

Technique for using AutoFixture to integration test an application using Castle Windsor

I'm new to AutoFixture, so I don't know if the following idea is going to make sense or be a reasonable thing to do. I've got an application that I'm in charge of integration testing, and it makes heavy use of Castle Windsor. To simplify dependency management and make my tests more like the application code, I've been building the Windsor container in my test initialize method and the using container.Resolve to instantiate the code I'm testing. I'd like to move away from that approach since it has limited my flexibility in certain situations.
What I'd like to do is have tests that look something like this:
[Theory]
[Dependency]
public void TestWithDependencies(IThing thing)
{
thing.Hello();
}
To make this happen, I can do the following:
public sealed class DependencyAttribute : AutoDataAttribute
{
public DependencyAttribute()
: base(new Fixture().Customize(new WindsorCustomization()))
{
}
}
public class WindsorCustomization : ICustomization
{
public WindsorCustomization()
{
// build container here using SUT installers
}
public void Customize(IFixture fixture)
{
fixture.Inject<IThing>(new Thing());
}
}
Doing this does work, but what I'd like to avoid is needing to copy every interface to implementation mapping from the Windsor container into the AutoFixture IFixture.
You should be able to do something like this:
public class WindsorCustomization : ICustomization
{
private readonly IWindsorContainer container;
public WindsorCustomization()
{
// build this.container here using SUT installers
}
public void Customize(IFixture fixture)
{
fixture.Customizations.Add(new WindsorAdapter(this.container));
}
}
public WindsorAdapter : ISpecimenBuilder
{
private readonly IWindsorContainer container;
public WindsorAdapter(IWindsorContainer container)
{
this.container = container;
}
public object Create(object request, ISpecimenContext context)
{
var t = request as Type;
if (t == null || !this.container.Kernel.HasComponent(t))
return new NoSpecimen(request);
return this.container.Resolve(t);
}
}
The WindsorAdapter sits in the Customizations collection, which is fairly early in AutoFixture's Tree of Responsibility, so it gets a chance to handle every (or most) incoming requests. If the request is a Type instance and the WindsorContainer has a component for that type, the adapter delegates the work of resolving the type to the container.
Otherwise, it returns a NoSpecimen instance, which is basically AutoFixture's way of signaling that this particular ISpecimenBuilder couldn't handle the request. Some other component in the AutoFixture Tree of Responsibility then gets the chance to handle the request.

Categories