如何解决在 .Net Core 中为单元测试编写更好的装置 GetClientsInteractorTest.csGetClientsInteractorTestsFixture.cs
我对 .Net Core 中的单元测试还很陌生。我正在为 Interactor
类编写单元测试,该类的职责是使用 Client
依赖项通过电子邮件或名称获取IClientGateway
。我使用过 XUnit
、Moq.AutoMock
和 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,"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,new GetClientsRequest(){ Name = "Victor" },new GetClientsResponse(){ Clients = new List<ClientDto>()
{
new ClientDto()
{
Id = 1,Email = "someEmail@someProvider.com"
}
}
}
},new GetClientsRequest(){ Email = "someEmail@someProvider.com"},};
}
单元测试本身 (ShouldReturnClients
) 起初非常简单,但它需要 4 个参数(加上 AutoMocker
)作为测试装置,可在 GetClientsInteractorTestsFixture
中找到。有没有更好的方法通过减少重复来制作这个测试装置?也许使用类似 AutoFixture
的东西?
解决方法
简短的回答是 - 是的,AutoFixture 可以帮助您减少样板文件并保持测试干燥。 下面是您使用 AutoFixture 进行的测试可能看起来像什么。 有关使用 AutoFixture 的更多详细信息,您可以访问 documentation,查看 Pluralsight course,在 Mark Seeman 的 blog 上阅读 AutoFixture,或在 AutoFixture 的 GitHub Q&A section 上寻求帮助。
[Theory]
[MemberAutoDomainData(nameof(GetClientsInteractorTestsFixture.Params))]
public async Task ReturnsExpectedResponse(
GetClientsRequest request,GetClientsResponse expectedResponse,GetClientsInteractor sut)
{
var actual = await sut.Handle(request,default);
actual.Should().Be(expectedResponse);
}
[Theory]
[MemberAutoDomainData(nameof(GetClientsInteractorTestsFixture.ParamsWithName))]
public async Task RequestsClientsByNameWhenRequestContainsName(
[Frozen] Mock<IClientGateway> gateway,GetClientsRequest request,GetClientsInteractor sut)
{
await sut.Handle(request,default);
gateway.Verify(
x => x.GetByNameAsync(request.Name,It.IsAny<CancellationToken>()),Times.Once(),"GetByNameAsync was not called");
}
[Theory]
[MemberAutoDomainData(nameof(GetClientsInteractorTestsFixture.Params))]
public async Task RequestsClientsByNameWhenRequestNameEmpty(
[Frozen] Mock<IClientGateway> gateway,default);
gateway.Verify(
x => x.GetByEmailAsync(request.Email,"GetByEmailAsync was not called");
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。