【问题标题】:AutoFixture with AutoMoq and concrete object injection带有 AutoMoq 和具体对象注入的 AutoFixture
【发布时间】:2013-11-15 14:23:47
【问题描述】:

我面临一个与AutoFixtureAutoMoqCustomization 相关的奇怪问题,以及它如何处理具体类的自动模拟。我怀疑我没有很好地使用它,但想知道有什么问题。首先是她的一些背景。假设我有一个要测试的课程:

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&lt;IdentityApplicationService&gt;() 时,在它的构造函数中注入了一个具体的 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 会这样。

【问题讨论】:

  • AutoMoq 忽略具体类,这就是您看到这种行为的原因:blog.ploeh.dk/2010/08/25/…IOW,这是意料之中的。
  • 虽然我理解这是意料之中的,但这是否也违反了最小意外原则?
  • 我不知道 - 惊喜取决于你的期望......在这种情况下,如果 all 实例突然变成 Mocks,我认为你也会感到惊讶他们的类型......事实上,我不确定我是否能理解这种行为变化的全部含义......这也是设计它现在的一个激励因素。

标签: c# autofixture moq-3 automoq


【解决方案1】:

正如 Mark Seemann points out,这是预期的行为。

以下是来自the original post 的代码,已更新以适用于当前版本的 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 类保持不变。

【讨论】:

    猜你喜欢
    • 2019-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-09
    • 2022-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多