在Autofixture中是否有一些简单的方法可以使用它的构造函数来创建一个对象,但硬编码/指定用于构造函数中单个参数的值?
我看到这可以通过属性完成,使用类似:
fixture.Build<MyObj>().With(x=x.Val,"hard coded value").Create()
答案 0 :(得分:11)
从评论中关于这个问题的讨论:
我经常想要新建一个对象,但我只关心一个参数。也许参数值驱动某种计算或转换。我希望值本身是随机的,但测试需要知道选择了什么随机值。
假设这是潜在的问题,我将尝试解决这个问题。
询问对象
最简单的解决方案是在AutoFixture创建后简单地询问对象的值:
var fixture = new Fixture();
var mc = fixture.Create<MyClass>();
var specialValue = mc.SpecialValue;
// Do something with specialValue...
如果您只需要了解特殊值是什么,但是您不需要它具有特定值,则可以使用此技术。
这显然要求您将构造函数参数中的值公开为(只读)属性,但是a good idea to do anyway。
创建后分配值
如果您需要参数具有特定值,则可以在创建后分配:
var fixture = new Fixture();
var mc = fixture.Create<MyClass>();
mc.SpecialValue = "Some really special value";
这要求您将值作为可写属性提供。虽然我个人并不是这方面的忠实粉丝,因为这会使对象变得可变,但很多人已经按照这种方式设计了他们的对象,如果是这样的话,为什么不利用它呢?
创建后使用复制和更新
如果您希望对象不可变,您仍然可以使用上述技术的变体。在F#中,您可以使用所谓的copy and update expressions来实现相同的目标。在F#中,它类似于:
let fixture = Fixture ()
let mc = {
fixture.Create<MyRecord> ()
with SpecialValue = "Some special value!" }
您可以通过提供类复制和更新方法在C#中进行模拟,这样您就可以编写如下内容:
var fixture = new Fixture();
var mc = fixture
.Create<MyClass>()
.WithSpecialValue("Some really special value");
这是我在C#代码中一直使用的技术。 AutoFixture有an idiomatic assertion to test such copy and update methods。
为参数注入值
如果您可以为特定构造函数参数注入固定值,则可以使用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<MyClass>();
Assert.Equal("Ploeh", actual.SpecialValue);
}
然而,这导致总是的参数是&#34; Ploeh&#34;对于那个fixture
实例。它也是重构 - 不安全的,因为它基于一个引用参数名称的字符串。