问题 如何告诉AutoFixture在实例化TBase时始终创建TDerived?


我有一个深度嵌套的对象模型,其中一些类可能看起来像这样:

class TBase { ... }

class TDerived : TBase { ... }

class Container
{
    ICollection<TBase> instances;
    ...
}

class TopLevel
{
    Container container1;
    Container container2;
    ...
}

我想创建我的顶级对象作为测试夹具,但我想要所有的 TBase 实例(例如在 instances 上面的集合)是实例 TDerived 而不是 TBase

我以为我可以简单地使用以下内容来做到这一点:

var fixture = new Fixture();

fixture.Customize<TBase>(c => c.Create<TDerived>());

var model = this.fixture.Create<TopLevel>();

...但这不起作用,因为lambda表达式 Customize 是错的。我猜这是有办法做到这一点,但AutoFixture似乎缺乏文档,而不是开发人员博客上的意识流。

谁能指出我正确的方向?


8782
2017-12-02 10:29


起源



答案:


虽然dcastro的答案也是一个选项,但最安全的选择是使用 TypeRelay 类。

fixture.Customizations.Add(
    new TypeRelay(
        typeof(TBase),
        typeof(TDerived));

8
2017-12-02 10:57



谢谢。我希望有记录...... :-) - Gary McGill
它是: nudoq.org/#!/Packages/AutoFixture/Ploeh.AutoFixture/TypeRelay :) - Mark Seemann
因此,“文档”是:“将类型的请求中继到类型的请求”,这实际上并没有使它听起来有用:-)但是我的更广泛的观点是,即使这样也很难找到信息,除非你知道在哪里看,或通读整个API - 就像使用字典查找一个你不知道如何拼写的单词。需要有一个更完整的教程或备忘单,否则99%的潜在用户群将在第一个障碍中被推迟,这将是一个真正的耻辱,考虑到显而易见的努力量。 - Gary McGill
我希望我听起来不感恩 - 无论是答案还是图书馆的实际发展。在这两种情况下,我都很感激你的时间 - 我只是认为更多的文档可能会产生巨大的差异 - 并且可能意味着你花更少的时间来回答这样的问题:-) - Gary McGill
我不是在争论,你的观点很好。这是OSS的永久性问题:没有人想写文档。 AutoFixture确实接受拉取请求,但:) - Mark Seemann


答案:


虽然dcastro的答案也是一个选项,但最安全的选择是使用 TypeRelay 类。

fixture.Customizations.Add(
    new TypeRelay(
        typeof(TBase),
        typeof(TDerived));

8
2017-12-02 10:57



谢谢。我希望有记录...... :-) - Gary McGill
它是: nudoq.org/#!/Packages/AutoFixture/Ploeh.AutoFixture/TypeRelay :) - Mark Seemann
因此,“文档”是:“将类型的请求中继到类型的请求”,这实际上并没有使它听起来有用:-)但是我的更广泛的观点是,即使这样也很难找到信息,除非你知道在哪里看,或通读整个API - 就像使用字典查找一个你不知道如何拼写的单词。需要有一个更完整的教程或备忘单,否则99%的潜在用户群将在第一个障碍中被推迟,这将是一个真正的耻辱,考虑到显而易见的努力量。 - Gary McGill
我希望我听起来不感恩 - 无论是答案还是图书馆的实际发展。在这两种情况下,我都很感激你的时间 - 我只是认为更多的文档可能会产生巨大的差异 - 并且可能意味着你花更少的时间来回答这样的问题:-) - Gary McGill
我不是在争论,你的观点很好。这是OSS的永久性问题:没有人想写文档。 AutoFixture确实接受拉取请求,但:) - Mark Seemann


使用 Register 告诉AutoFixture如何创建特定类型的实例的方法。

fixture.Register<TBase>(() => new TDerived());

或者,正如@sgnsajgon所指出的那样:

fixture.Register<TBase>( fixture.Create<TDerived> );

7
2017-12-02 10:42



你也可以写:fixture.Register <TBase>(fixture.Create <TDerived>); - sgnsajgon
@sgnsajgon很好,我已添加到答案:) - dcastro
谢谢,这很有效。 +1。然而,很难与马克·西曼争辩,所以我接受了他的“更正确”的答案。 - Gary McGill
@GaryMcGill你做对了,我甚至不知道 TypeRelay :) - dcastro