Autofixture中是否有一些简单的方法来使用它的构造函数新建对象,但硬编码/指定用于构造函数中单个参数的值?简单的方法来指定单个构造函数参数的值?
我看到,这可以用属性来实现,使用类似:
fixture.Build<MyObj>().With(x=x.Val,"hard coded value").Create()
Autofixture中是否有一些简单的方法来使用它的构造函数新建对象,但硬编码/指定用于构造函数中单个参数的值?简单的方法来指定单个构造函数参数的值?
我看到,这可以用属性来实现,使用类似:
fixture.Build<MyObj>().With(x=x.Val,"hard coded value").Create()
从讨论这个问题的意见:
我常想新机一个对象,但我只关心一个参数。也许参数值驱动某种计算或变换。我希望价值本身是随机的,但测试需要知道选择了什么样的随机值。
假设这是潜在的问题,我会尝试解决这个问题。
询问对象
最简单的方法是简单地询问对象的值是什么,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);
}
然而,这将导致该参数始终是“Ploeh”为fixture
实例。它也是重构 - 不安全的,因为它基于引用参数名称的字符串。
嗨马克 - 非常感谢您的详细回复。这些都是很好的解决方法,与您提供的完全相同。共同的主题是,你必须调整你的对象,以便它可以被测试。这对我来说有点代码味道。似乎没有办法在不修改对象的情况下完成我期望的操作。 – SFun28 2015-02-11 14:22:02
它被称为*测试驱动开发*。整个观点是测试提供关于API设计可用性的反馈。 – 2015-02-11 14:55:01
只有当你使用TDD时=)我认为Autofixture是独立于TDD的非常有用的。无论如何,这不是TDD的味道吗?您添加这些属性的唯一原因是由于Autofixture的缺陷。它与TDD的原理无关。 – SFun28 2015-02-11 15:57:17
C#实际上并没有类型安全的语法来引用方法中的单个参数(包括构造函数),所以除非将整个构造函数拉入lambda表达式中,否则这不是真正可行的。这点你不妨直接使用构造函数创建对象,但不使用AutoFixture。你想要这样做的动机是什么?在IME中,通常有一种以不同方式实现大多数相关目标的好方法,但您可能需要以不同的方式来看问题。 – 2015-02-05 17:42:13
希望有一些非类型安全但方便的方式,如Func,其中输入将作为参数的名称作为字符串。我的一般动机是单元测试。我经常想要新建一个对象,但我只关心一个参数。也许参数值驱动某种计算或变换。我希望价值本身是随机的,但测试需要知道选择了什么样的随机值。鉴于此,单元测试可能会得到一个Property或调用在其操作中使用构造函数参数值的方法。 –
SFun28
2015-02-05 17:47:11
[这个答案](http://stackoverflow.com/a/27774580/11635)或[我对这个CodePlex讨论底部的答案]的一些变化](https://autofixture.codeplex.com/discussions/231342)可能会让你开心 – 2015-02-16 09:45:09