首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用AutoMoq属性模拟构造函数依赖项

使用AutoMoq属性模拟构造函数依赖项
EN

Stack Overflow用户
提问于 2016-04-28 15:18:18
回答 2查看 1.4K关注 0票数 2

我想知道,在使用设置AutoData的测试用例之前,在调用测试下系统的构造函数(SUT)之前,是否有一种为依赖项设置模拟的方法。

我的儿子看起来:

代码语言:javascript
复制
class Sut
{
    private readonly IFoo foo;
    public Sut(IFooFactory factory)
    {
        this.foo = factory.Build(1, 2);
    }

    public IFoo Foo
    {
        get
        {
            return this.foo;
        }
    }
}

所以我正在写的测试看起来是:

代码语言:javascript
复制
[Theory]
[AutoData]
internal void Foo_IsCorrectlySet_Test(
    [Frozen] Mock<IFooFactory> fooFactory,
    IFoo foo,
    Sut sut)
{
    fooFactory.Setup(mock => mock.Build(1, 2))
        .Returns(foo)
        .Verifiable();

    var actual = sut.Foo;

    Assert.Equal(foo, sut);
    fooFactory.Verify();
}

显然,当Sut的构造函数在我能够设置IFooFactory之前运行时,这个测试就失败了。因此,我想我可能已经能够在测试中将Sut的声明更改为Lazy<Sut>。但是,在实际测试代码运行之前,构造函数仍然运行,这意味着我的测试将失败。

现在,我知道我可以很容易地用一个实际的Fixture对象来设置这个测试,并在调用创建Sut之前手动创建所有的对象并设置它们,这很好,但是我希望测试保持大致相同,因此我想知道是否还有一种方法可以使用AutoData属性来设置测试,但在所有设置完成之后才运行构造函数?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-04-28 20:32:18

AutoFixture最初是作为测试驱动开发( TDD )工具构建的,而TDD完全是关于反馈的。本着古斯的精神,您应该听您的测试。如果测试很难编写,您应该考虑API的设计。AutoFixture倾向于放大这种反馈,这可能也是如此。

考虑Sut类的不变量。因为它有一个只读IFoo类字段,所以我将其解释为IFoo是类的一个依赖项。

如果是这样的话,那么通过构造函数注入IFoo,而不是IFooFactory

代码语言:javascript
复制
public class Sut
{
    private readonly IFoo foo;
    public Sut(IFoo foo)
    {
        this.foo = foo;
    }

    public IFoo Foo
    {
        get { return this.foo; }
    }
}

您仍然可以在应用程序的IFooFactory中使用成分根编写它

代码语言:javascript
复制
var sut = new Sut(aFactory.Build(1, 2));

这将使测试更易于编写。我甚至不能向您展示这个重构的上述测试,因为它是多余的,可以(而且应该)删除。

上述最初的设计违反了尼古拉·马洛维奇( Nikola )关于IoC的第四定律,即构造函数不应该做任何工作。

票数 5
EN

Stack Overflow用户

发布于 2016-04-28 15:25:50

您可以使用夹具对象模式。这允许您在创建sut之前设置您的模拟程序。

行文中的某物:

代码语言:javascript
复制
    private class Fixture
    {
        public Mock<FooFactory> FooFactoryMock { get; set; } = new Mock<FooFactory>();
        public Sut GetSut()
        {
            return new Sut(FooFactoryMock.Object);
        }
    }

    [Theory]
    [AutoData]
    internal void Foo_IsCorrectlySet_Test(
        IFoo foo)
    {
        var fixture = new Fixture();
        fixture.FooFactory.Setup(mock => mock.Build(1, 2))
            .Returns(foo)
            .Verifiable();

        var sut = fixture.GetSut();
        var actual = sut.Foo;

        Assert.Equal(foo, sut);
        fooFactory.Verify();
    }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36918881

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档