指定单个构造函数参数值的简单方法?
Easy way to specify the value of a single constructor parameter?
在 Autofixture 中是否有一些简单的方法可以使用它的构造函数来新建对象,但是 hard-code/specify 构造函数中用于单个参数的值?
我看到这可以通过属性来完成,使用类似的东西:
fixture.Build<MyObj>().With(x=x.Val,"hard coded value").Create()
来自评论中对此问题的讨论:
Often I want to new-up an object, but I'm only concerned about a single parameter. Maybe the parameter value drives a calculation or transform of some sort. I want the value itself to be random, but the test needs to know what random value was chosen.
假设这是根本问题,我会尝试解决这个问题。
问对象
最简单的解决方案是在 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!" }
您可以通过提供 类 copy-and-update 方法在 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);
}
但是,这会导致该参数 始终 为 fixture
实例的 "Ploeh"。它也是重构不安全的,因为它基于引用参数名称的字符串。
在 Autofixture 中是否有一些简单的方法可以使用它的构造函数来新建对象,但是 hard-code/specify 构造函数中用于单个参数的值?
我看到这可以通过属性来完成,使用类似的东西:
fixture.Build<MyObj>().With(x=x.Val,"hard coded value").Create()
来自评论中对此问题的讨论:
Often I want to new-up an object, but I'm only concerned about a single parameter. Maybe the parameter value drives a calculation or transform of some sort. I want the value itself to be random, but the test needs to know what random value was chosen.
假设这是根本问题,我会尝试解决这个问题。
问对象
最简单的解决方案是在 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!" }
您可以通过提供 类 copy-and-update 方法在 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);
}
但是,这会导致该参数 始终 为 fixture
实例的 "Ploeh"。它也是重构不安全的,因为它基于引用参数名称的字符串。