【问题标题】:How can I tell AutoFixture to always create TDerived when it instantiates a TBase?我如何告诉 AutoFixture 在实例化 TBase 时始终创建 TDerived?
【发布时间】:2014-12-02 10:29:05
【问题描述】:

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

class TBase { ... }

class TDerived : TBase { ... }

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

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

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

我想我可以很简单地使用类似的东西来做到这一点:

var fixture = new Fixture();

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

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

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

谁能指出我正确的方向?

【问题讨论】:

    标签: c# autofixture


    【解决方案1】:

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

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

    【讨论】:

    • 谢谢。我确实希望记录在案... :-)
    • 所以,“文档”是:“将对类型的请求中继到对类型的请求”,这实际上并没有让它听起来那么有用:-) 但我更广泛的观点是除非您知道在哪里查找,或者通读整个 API,否则即使是这些很少的信息也无法找到 - 这就像使用字典查找您不知道如何拼写的单词一样。需要有一个更完整的教程或备忘单,否则 99% 的潜在用户群将在第一个障碍时被推迟,考虑到显然付出的努力,这将是一个真正的耻辱。
    • 我希望我听起来不是忘恩负义——首先是为了答案,以及图书馆的实际开发。感谢您在这两种情况下的时间 - 我只是认为多一点文档可能会产生巨大的影响 - 并且可能意味着您花更少的时间回答这样的问题:-)
    • 我并不是在争论,你的观点是正确的。这就是 OSS 永远存在的问题:没人想写文档。不过,AutoFixture 确实接受拉取请求 :)
    【解决方案2】:

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

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

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

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

    【讨论】:

    • 你也可以这样写:fixture.Register(fixture.Create);
    • @sgnsajgon 很好,我已将其添加到答案中:)
    • 谢谢,成功了。 +1。但是,很难与 Mark Seemann 争论,所以我接受了他“更正确”的答案。
    • @GaryMcGill 你做对了,我什至不知道TypeRelay :)
    猜你喜欢
    • 2013-03-09
    • 1970-01-01
    • 2021-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-12
    • 1970-01-01
    • 2013-12-18
    相关资源
    最近更新 更多