【问题标题】:How to create new instances of objects with custom SpecimenBuilder with AutoFixture如何使用 AutoFixture 自定义 SpecimenBuilder 创建对象的新实例
【发布时间】:2020-09-12 16:52:25
【问题描述】:

目前我有这样的代码:

private ConnectedClient WithConnection(IConnection connection)
{
    var builder = new ClientWithConnectionSpecimenBuilder(connection);

    Fixture.Customizations.Add(builder);
    var client = Fixture.Create<ConnectedClient>();
    Fixture.Customizations.Remove(builder);

    return client;
}

基本上我需要在我的测试代码中使用指定的连接创建ConnectedClient 类的新实例。我已经建立了定制的标本生成器来做到这一点。

但是没有像

这样的方法
Fixture.Create<T>(specimenBuilder) 

所以我需要自定义夹具。

“Fixture”是我的基础测试类的继承保护属性,它已经设置了一些自定义 AutoMoqData 自定义,因此我需要重用它来创建对象。

【问题讨论】:

  • 我需要创建多个具有不同特定连接的不同对象,这就是为什么我不能只对整个 Fixture 对象使用自定义。

标签: c# .net unit-testing xunit autofixture


【解决方案1】:

应该可以使用一次性的Build 方法来使用特定的样本生成器进行自定义:

var client = fixture.Build<ConnectedClient>().FromFactory(builder).Create();

请注意,这样做会禁用灯具的任何其他自定义。

DSL 支持使用WithWithout 进行更多的自定义,因此如果您想对属性进行一些额外的自定义,您可以这样做:

var client = fixture.Build<ConnectedClient>()
    .FromFactory(builder)
    .With(cc => cc.SomeProperty, () => fixture.Build<T>().FromFactory(otherFactory).Create())
    .Create();

但是对于重要的自定义,这将变得相当乏味。 Autofixture 以这种方式固执己见。

Build 方法实际上旨在作为一次性解决方案。如果您想更多地依赖 Autofixture 的机器来做所有事情除了来创建客户端连接,我建议依靠现有的Freeze 方法和Frozen 属性来保持注入的@987654329 @ 给定的ConnectedClient 相同,这样就不需要特定的ISpecimenBuilder

【讨论】:

  • 如果我想要多个自定义项怎么办?我可以以某种方式链接 FromFactory 方法吗?
  • 您如何想象多个标本生成器将用于单一类型?如果不是针对单一类型,您能详细说明您的意思吗?
  • 例如,使用我当前的方法,我可以为对象的不同参数添加自定义:想象在我的示例中,有几个对 Customizations.Add 的调用,我正在为不同的参数添加不同的自定义传递给对象的构造函数(例如,长度为 10 个字符的 ID 和连接参数作为示例中的特定对象)。然后,除了特定的连接,我还要设置 Id 参数。
  • 所以,是的,样本构建器适用于不同的类型(或者甚至适用于相同类型但我正在构建的对象的构造函数的不同参数)。
  • 我更新了答案以扩展构建 DSL。关于 autofixture 支持的内容,您的目标是相反的。由您决定哪种感觉更清晰/更干净。
猜你喜欢
  • 1970-01-01
  • 2021-12-19
  • 1970-01-01
  • 1970-01-01
  • 2020-07-12
  • 2020-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多