轻松指定单个构造函数参数的值?

在Autofixture中是否有一些简单的方法来使用它的构造函数来创建对象,但硬编码/指定用于构造函数中的单个参数的值?

我看到这可以通过属性来完成,使用类似于:

fixture.Build().With(x=x.Val,"hard coded value").Create()

从评论中关于这个问题的讨论:

我经常想要新建一个对象,但我只关心一个参数。 也许参数值驱动某种计算或转换。 我希望值本身是随机的,但测试需要知道选择了什么随机值。

假设这是潜在的问题,我将尝试解决这个问题。

问对象

最简单的解决方案是在AutoFixture创建后简单地询问对象的值:

 var fixture = new Fixture(); var mc = fixture.Create(); var specialValue = mc.SpecialValue; // Do something with specialValue... 

如果您只需要知道特殊值是什么,但是您不需要它具有特定值,则可以使用此技术。

这显然要求您将构造函数参数中的值作为(只读)属性公开,但无论如何这都是一个好主意 。

创建后分配值

如果您需要参数具有特定值,则可以在创建后分配它:

 var fixture = new Fixture(); var mc = fixture.Create(); mc.SpecialValue = "Some really special value"; 

这要求您将值作为可写属性提供。 虽然我个人不是那个人的忠实粉丝,因为这会使对象变得可变,但很多人已经按照这种方式设计了他们的对象,如果是这样的话,为什么不利用它呢?

创建后使用copy-and-update

如果您希望对象是不可变的,您仍然可以使用上述技术的变体。 在F#中,您可以使用所谓的复制和更新表达式来实现相同的目标。 在F#中,它类似于:

 let fixture = Fixture () let mc = { fixture.Create () with SpecialValue = "Some special value!" } 

您可以通过提供类复制和更新方法在C#中模拟它,这样您就可以编写如下内容:

 var fixture = new Fixture(); var mc = fixture .Create() .WithSpecialValue("Some really special value"); 

这是我在C#代码中一直使用的技术。 AutoFixture有一个惯用的断言来测试这样的复制和更新方法 。

注入参数的值

如果您可以为特定构造函数参数注入固定值,则可以使用AutoFixture内核的构建块执行此操作。 此测试演示如何:

 [Fact] public void CustomizeParameter() { var fixture = new Fixture(); fixture.Customizations.Add( new FilteringSpecimenBuilder( new FixedBuilder("Ploeh"), new ParameterSpecification( typeof(string), "specialValue"))); var actual = fixture.Create(); Assert.Equal("Ploeh", actual.SpecialValue); } 

但是,这会导致该参数始终为该fixture实例的“Ploeh”。 它也是重构 – 不安全,因为它基于一个引用参数名称的字符串。