AutoFoture与AutoMoq和具体对象注入

Tom*_*uλa 3 c# autofixture moq-3 automoq

我面临着与一个奇怪的问题AutoFixture,并AutoMoqCustomization和它如何与具体类的automocking交易.我怀疑我没有很好地使用它,但想知道问题是什么.首先是她的一些背景.假设我有一个我想测试的课程:

public class IdentityApplicationService
{
    public IdentityApplicationService(
        TenantProvisioningService tenantProvisioningService)
    {
        // guard clause etc.
        _tenantProvisioningService = tenantProvisioningService;
    }
}
Run Code Online (Sandbox Code Playgroud)

及其依赖类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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的简单测试:

[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
}
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为当我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
}
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:我做错了还是它应该是这样的?如果没有,请给我解释为什么AutoFixture表现得像这样.

Nik*_*nis 6

正如Mark Seemann 指出的那样,这是预期的行为.

以下是更新的原始帖子中的代码,以使用当前版本的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())));
Run Code Online (Sandbox Code Playgroud)

FilteringRelays级保持不变.