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

SFu*_*n28 10 c# autofixture

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

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

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

Mar*_*ann 11

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

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

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

问对象

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

var fixture = new Fixture();
var mc = fixture.Create<MyClass>();
var specialValue = mc.SpecialValue;
// Do something with specialValue...
Run Code Online (Sandbox Code Playgroud)

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

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

创建后分配值

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

var fixture = new Fixture();
var mc = fixture.Create<MyClass>();
mc.SpecialValue = "Some really special value";
Run Code Online (Sandbox Code Playgroud)

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

创建后使用copy-and-update

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

let fixture = Fixture ()
let mc = {
    fixture.Create<MyRecord> ()
    with SpecialValue = "Some special value!" }
Run Code Online (Sandbox Code Playgroud)

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

var fixture = new Fixture();
var mc = fixture
    .Create<MyClass>()
    .WithSpecialValue("Some really special value");
Run Code Online (Sandbox Code Playgroud)

这是我在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<MyClass>();

    Assert.Equal("Ploeh", actual.SpecialValue);
}
Run Code Online (Sandbox Code Playgroud)

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

  • 自从引入了 `nameof` 运算符 `new ParameterSpecification( typeof(string), nameof(MyClass.SpecialValue)));`以来,它实际上比以前安全得多 (2认同)