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.