AutoFixture com AutoMoq e injeção de objetos concretos
-
20-12-2019 - |
Pergunta
Estou enfrentando um problema estranho relacionado a AutoFixture
e AutoMoqCustomization
e como ele lida com a zombaria automática de classes concretas.Suspeito que não estou usando muito bem, mas gostaria de saber qual é o problema.Primeiro de tudo, ela tem algum contexto.Digamos que eu tenha uma classe que desejo testar:
public class IdentityApplicationService
{
public IdentityApplicationService(
TenantProvisioningService tenantProvisioningService)
{
// guard clause etc.
_tenantProvisioningService = tenantProvisioningService;
}
}
e sua classe de dependência TenantProvisioningService
(As dependências do TenantProvisioningService não são relevantes aqui porque serão simuladas automaticamente e não me importo com isso no meu teste):
public class TenantProvisioningService
{
readonly IRoleRepository _roleRepository;
readonly ITenantRepository _tenantRepository;
readonly IUserRepository _userRepository;
public TenantProvisioningService(
ITenantRepository tenantRepository,
IUserRepository userRepository,
IRoleRepository roleRepository)
{
this._roleRepository = roleRepository;
this._tenantRepository = tenantRepository;
this._userRepository = userRepository;
}
}
e aqui está meu teste simples:
[Fact]
public void ShouldReturnTenantWhenCallingProvisionTenant()
{
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var mockTenantProvisioningService =
fixture.Freeze<Mock<TenantProvisioningService>>();
var sut = fixture.Create<IdentityApplicationService>();
var command = new ProvisionTenantCommand(
"bla",
"bla SaaS platform",
"superadmin",
"superadmin",
"admin@bla.bla",
null,
null,
null,
null,
null,
null,
null);
var tenant = sut.ProvisionTenant(command);
// some asserts
}
Isso não funciona porque quando eu ligo fixture.Create<IdentityApplicationService>()
então, em seu construtor, um TenantProvisioningService concreto é injetado em vez de um proxy que você pode encontrar em mockTenantProvisioningService.Object.
Se eu reescrever o teste assim (observe a linha de injeção do fixture) tudo funcionará como esperado (pelo menos por mim :))
[Fact]
public void ShouldReturnTenantWhenCallingProvisionTenant()
{
var fixture = new Fixture().Customize(new AutoMoqCustomization());
var mockTenantProvisioningService =
fixture.Freeze<Mock<TenantProvisioningService>>();
fixture.Inject(mockTenantProvisioningService.Object);
var sut = fixture.Create<IdentityApplicationService>();
var command = new ProvisionTenantCommand(
"bla",
"bla SaaS platform",
"superadmin",
"superadmin",
"admin@bla.bla",
null,
null,
null,
null,
null,
null,
null);
var tenant = sut.ProvisionTenant(command);
// some asserts
}
Então minha pergunta é :Estou fazendo errado ou é como deveria ser?Caso contrário, por favor, me dê uma explicação de por que o AutoFixture está se comportando assim.
Solução
Como Mark Seemann aponta, este é o comportamento esperado.
Abaixo está o código de a postagem original atualizado para funcionar com a versão atual do AutoFixture:
Func<ISpecimenBuilder, bool> concreteFilter =
sb => !(sb is MethodInvoker);
var relays = new FilteringRelays(concreteFilter);
var fixture = new Fixture(relays).Customize(
new AutoMoqCustomization(
new MockRelay(
new TrueRequestSpecification())));
O FilteringRelays
classe permanece a mesma.