Autofixture,class 作为生成的 class 对象?

Autofixture, class as the generated class object?

我一直在研究,我开始认为这是可能的,但 Autofixture 有一些漏洞。

写一个假的 class,我在合法 class 中有一个 States class,我想在 [=35= 上定义为 Autofixture 生成的对象] 在我的 fakes 项目中实例化 class。

类似于以下内容:

namespace Geo.Fakes {
public class State : MySpace.State, {
    public cBRCState() : base() {
        this = new Fixture<MySpace.State>().Create(); //can't do this
    }
}

现在,很明显,您不能分配 this,因为它是只读的。我想实现 IFixtureISpecimenBuilder 接口并将构造函数更改为

public State () : base() {
    this.Create<MySpace.State>();
}
...
public object Create(object request, ISpecimenContext context) {
    return new Fixture().Create<MySpace.State>(); //can't do this either, recursive 
}

但我不是在摸索如何让它真正起作用。我这里的方向是否正确?

编辑:澄清一下,这不是为了测试。这是为了向第三方提供虚假数据,而不让他们访问我们的真实数据或网络。目标是让我们的假 class 代替真实的库,以便代码相同。所以在我们的示例中,如果我说 MySpace.State state = new MySpace.State()fake.State state = new fake.State(),我需要返回相同的对象,无论我们指向的是假库还是真实库。由于 Autofixture 创建了一个类型的对象并在您 fixture.Create<MySpace.State>() 时将其交还,我需要一个假的 State class 来使用 Autofixture 实例化并充当 MySpace.State 即使这是假的。

如果我对问题的理解正确,其目的是通过让第三方使用 Adapter API 来区分内部和外部行为。在那种情况下,我认为您最好的选择是使用静态工厂方法,如下所示:

namespace Ploeh.Whosebug.Q47914153.Geo.Fakes
{
    public class State : MySpace.State
    {
        private State()
        {
        }

        public static State Create()
        {
            return new Fixture().Build<State>().FromFactory(() => new State()).Create();
        }
    }
}

请注意构造函数是 private 以防止客户端开发人员创建 'empty' 对象。 (并不是说我认为这是一个好的模式,但这似乎符合 OP 中的描述。最终,这是你的脚。)

默认情况下,AutoFixture 将忽略私有构造函数,它的第二个选项是寻找静态工厂方法...如Create。如果您简单地使用 Fixture.Create,这确实会创建一个无限递归。避免这种情况的技巧是使用 Build API,结合 FromFactory,因为虽然 AutoFixture 默认考虑 private 成员禁忌,但它仍然会愉快地调用 () => new State() lambda 表达式。

此测试通过:

[Fact]
public void DemoOfFactory()
{
    var state = Geo.Fakes.State.Create();

    Assert.IsType<Geo.Fakes.State>(state);
    Assert.NotEqual(default(string), state.TheText);
    Assert.NotEqual(default(int), state.TheNumber);
}

虽然我不确定我是否理解这种情况下的所有要求,但总体方法中的一些内容对我来说并不真实。当复杂的创建逻辑对我隐藏时,我总是感到不安。

除了依赖随机值生成和继承,你可以使用 Builder 模式吗?这是一个 article about Test Data Builders,虽然我怀疑您不需要它进行单元测试,但您可以忽略 Test Data Builder[=36 中的第一个词=]...