I'm fairly new to unit testing in the .Net Core. I'm writing unit tests for an Interactor
class, whose responsibility is to getClient
s either by email or name using the IClientGateway
dependency. I've used XUnit
, Moq.AutoMock
and FluentAssertions
.
GetClientsInteractorTest.cs
[Trait("Clients", "GetClientsInteractor")]
[Collection(nameof(GetClientsInteractorTestsCollectionFixture))]
public class GetClientsInteractorTests
{
private readonly GetClientsInteractorTestsFixture fixture;
public GetClientsInteractorTests(GetClientsInteractorTestsFixture fixture) =>
this.fixture = fixture;
[Theory(DisplayName = "should return clients in clientsGateway")]
[MemberData(nameof(GetClientsInteractorTestsFixture.Params), MemberType = typeof(GetClientsInteractorTestsFixture))]
public async Task ShouldReturnClients(IEnumerable<Client> mockedClients, CancellationTokenSource cancellationTokenSource,
GetClientsRequest request, GetClientsResponse expectedResponse)
{
// Arrange
fixture.Mocker.GetMock<IClientGateway>()
.Setup(ClientGateway => ClientGateway.GetByNameAsync(request.Name, cancellationTokenSource.Token))
.ReturnsAsync(mockedClients.Where(client => client.Name.Equals(request.Name)))
.Verifiable();
fixture.Mocker.GetMock<IClientGateway>()
.Setup(ClientGateway => ClientGateway.GetByEmailAsync(request.Email, cancellationTokenSource.Token))
.ReturnsAsync(mockedClients.Where(client => client.Email.Equals(request.Email)))
.Verifiable();
// Act
GetClientsResponse actualResponse =
await fixture.Mocker.CreateInstance<GetClientsInteractor>()
.Handle(request, cancellationTokenSource.Token);
// Assert
if(request.Name != null)
fixture.Mocker.GetMock<IClientGateway>()
.Verify(mock => mock.GetByNameAsync(request.Name, cancellationTokenSource.Token), Times.Once(), "GetByNameAsync was not called");
else if (request.Email != null)
fixture.Mocker.GetMock<IClientGateway>()
.Verify(mock => mock.GetByEmailAsync(request.Email, cancellationTokenSource.Token), Times.Once(), "GetByEmailAsync was not called");
actualResponse.Should()
.Be(expectedResponse);
}
}
GetClientsInteractorTestsFixture.cs
public class GetClientsInteractorTestsFixture
{
public AutoMocker Mocker = new AutoMocker(MockBehavior.Strict);
public static IEnumerable<Client> mockedClients = new Client[] {
new Client()
{
ClientId = 1,
Name = "Victor",
Email = "someEmail@someProvider.com"
},
};
public static CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
public static IEnumerable<object[]> Params = new[]
{
new object[]
{
mockedClients,
cancellationTokenSource,
new GetClientsRequest(),
new GetClientsResponse()
},
new object[]
{
mockedClients,
cancellationTokenSource,
new GetClientsRequest(){ Name = "Victor" },
new GetClientsResponse(){ Clients = new List<ClientDto>()
{
new ClientDto()
{
Id = 1,
Name = "Victor",
Email = "someEmail@someProvider.com"
}
}
}
},
new object[]
{
mockedClients,
cancellationTokenSource,
new GetClientsRequest(){ Email = "someEmail@someProvider.com"},
new GetClientsResponse(){ Clients = new List<ClientDto>()
{
new ClientDto()
{
Id = 1,
Name = "Victor",
Email = "someEmail@someProvider.com"
}
}
}
},
};
}
The unit test itself (ShouldReturnClients
) its quite simple at first, but it requires 4 parameters (plus AutoMocker
) as a test fixture, found in GetClientsInteractorTestsFixture
. Is there a better way to make this test fixture by making it less repetitive? perhaps using something like AutoFixture
?