AutoFixture с AutoMoq и внедрением бетонных объектов
-
20-12-2019 - |
Вопрос
Я столкнулся со странной проблемой, связанной с AutoFixture
и AutoMoqCustomization
и как он справляется с автомокингом конкретных классов.Я подозреваю, что использую его не очень хорошо, но хотел бы знать, в чем проблема.Прежде всего, у нее какой-то контекст.Допустим, у меня есть класс, который я хочу протестировать:
public class IdentityApplicationService
{
public IdentityApplicationService(
TenantProvisioningService tenantProvisioningService)
{
// guard clause etc.
_tenantProvisioningService = tenantProvisioningService;
}
}
и его класс зависимости TenantProvisioningService
(Зависимости TenantProvisioningService здесь не имеют значения, поскольку они будут автоматически имитироваться, и в моем тесте они меня не волнуют):
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;
}
}
и вот мой простой тест:
[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
}
Это не работает, потому что когда я звоню fixture.Create<IdentityApplicationService>()
затем в его конструктор вводится конкретный TenantProvisioningService вместо прокси, который вы можете найти в mockTenantProvisioningService.Object.
Если я перепишу тест следующим образом (обратите внимание на строку ввода прибора), все будет работать так, как ожидалось (по крайней мере, у меня :))
[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
}
Итак, мой вопрос :Я делаю это неправильно или так и должно быть?Если нет, пожалуйста, объясните мне, почему AutoFixture ведет себя так.
Решение
Как Марк Симанн указывает на то, это ожидаемое поведение.
Ниже приведен код из исходный пост обновлено для работы с текущей версией 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())));
А FilteringRelays
класс остается прежним.