我正在尝试使用 SUT工厂 “模式”来创建我的空缺。

给定SUT结构:

namespace MySut
{
    public class Dep1
    {
    }

    public class Dep2
    {
    }

    public class Sut
    {
        public Sut( Dep1 dep1, Dep2 dep2 )
        {
        }
    }
}

我正在使用 自动倒, ,并且想知道折叠以下规格和关联的SUT工厂方法的最佳方法是什么[有价值但]忙碌:

namespace MySpecifications
{
    using MySut;
    public class MySpecification
    {
        public void TestCore()
        {
            // Dont care about dependencies, testing core functionality
            var sut = CreateSut();
        }

        public void TestDep1Interaction()
        {
            // Dont care about Dep2, want to observe stuff on the Dep1 dependent object
            var sut = CreateSut( new Mock<Dep1>().Object );
        }

        public void TestDep2Interaction()
        {
            // Dont care about Dep1, want to observe stuff on the Dep2 dependent object
            var sut = CreateSut( new Mock<Dep2>().Object );
        }

        private object CreateSut( )
        {
            return CreateSut( CreateDep1(), CreateDep2() );
        }

        private object CreateSut( Dep1 dep1 )
        {
            return CreateSut( dep1, CreateDep2() );
        }

        private object CreateSut( Dep2 dep2 )
        {
            return CreateSut( CreateDep1(), dep2 );
        }

        private Sut CreateSut( Dep1 dep1, Dep2 dep2 )
        {
            return new Sut( dep1, dep2 );
        }

        private static Dep1 CreateDep1()
        {
            return new Fixture().CreateAnonymous<Dep1>();
        }

        private static Dep2 CreateDep2()
        {
            return new Fixture().CreateAnonymous<Dep2>();
        }
    }
}

像这样的东西:

    public class MyAutoFixturedSpecification
    {
        public void TestCore()
        {
            // Dont care about dependencies, testing core functionality
            var sut = CreateSut();
        }

        public void TestDep1Interaction()
        {
            // Dont care about Dep2, want to observe stuff on the Dep1 dependent object
            var sut = CreateSut( new Mock<Dep1>().Object );
        }

        public void TestDep2Interaction()
        {
            // Dont care about Dep1, want to observe stuff on the Dep2 dependent object
            var sut = CreateSut( new Mock<Dep2>().Object );
        }

        private object CreateSut( params object[] injectedNonAnonymouses )
        {
            return new Fixture(  ).Build<Sut>(  )./*??????*/;
        }
    }

或者:

    public class MyAnticipatedAutoFixturedSpecification
    {
        public void TestCore()
        {
            // Dont care about dependencies, testing core functionality
            var sut = new Fixture(  ).Build<Sut>().CreateAnonymous(  );
        }

        public void TestDep1Interaction()
        {
            // Dont care about Dep2, want to observe stuff on the Dep1 dependent object
            var sut = new Fixture().Build<Sut>()/*.With( new Mock<Dep1>().Object )*/.CreateAnonymous();
        }

        public void TestDep2Interaction()
        {
            // Dont care about Dep1, want to observe stuff on the Dep2 dependent object
            var sut = new Fixture().Build<Sut>()/*.With( new Mock<Dep2>().Object )*/.CreateAnonymous();
        }
    }

即,删除所有工厂垃圾,以便我的规格可以轻松地应对:

namespace MySutWithNewDependency
{
    public class Dep1
    {
    }

    public class Dep2
    {
    }

    public class Dep3
    {
    }

    public class Sut
    {
        public Sut( Dep1 dep1, Dep2 dep2, Dep3 dep3 )
        {
        }
    }
}

虽然与汽车容器的概念有重叠,但我仍然不是在寻找金锤 - 只是一种能够一次嘲笑0或1件事的方法,但能够自定义依赖对象的创建每当其依赖项集更改时,请重新访问SUT构造函数的明确调用。

(还使用xunit.net(subpec样式),毛口,ninject2(尽管不想在我的规格中使用di))

有帮助吗?

解决方案

自动固定可以或多或少地为您完成所有这些,而无需所有这些额外的脚手架。我将从基本的固定装置开始,然后用它来解决 Sut:

var fixture = new Fixture();
var sut = fixture.CreateAnonymous<Sut>();

这是假设的 Dep1Dep2 可以通过Autofuture自动创建,但是如所示,它们可以是因为它们具有默认的构造函数。

当您要覆盖特定类型时,可以使用这样的寄存器方法:

var fixture = new Fixture();

var mock = new Mock<Dep1>();
fixture.Register(mock.Object);
// Setup mock if necessary...

var sut = fixture.CreateAnonymous<Sut>();

这将导致 fixture 使用 mock.Object 随时 Dep1 需要,包括何时 Sut 调用构造函数。这绝对符合您面对不断发展的构造函数的强大要求,这是自动固定的主要原因之一。

在更现实的情况下,dep1和dep2可能是接口,在这种情况下,您可能希望将它们作为“默认固定装置”的一部分注册。这当然也可能是因为 最后一次注册胜利. 。这意味着您可以使用一些良好的默认设备配置固定实例,并且在需要时仍然能够覆盖特定类型。

我个人使用自动固定作为自动隔离容器。 讨论 提供了一个提示,即AutoFixture 1.1 API将如何实现,但是Autofixture 2.0的新内核将提供更好的可扩展性选项。当我掌握它时,我将写一篇有关此主题的博客文章。

PS对迟到的答复感到抱歉,但我以前没有看到您的问题。将来,请随时为我(例如在Twitter上)提供更快的答复。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top