单元测试 C# 属性
我正在处理一个具有很多属性的类。例如;
public class Bib
{
public int PartQty { get; set; }
}
现在进行单元测试;我做了像这里这样的 xUnit 测试
[Fact]
public void CanGetAndSetPartQuantity()
{
const int expected = 3;
var target = new Bib() {PartQty = expected};
Assert.Equal(expected, target.PartQty);
}
,我讨厌我如何硬编码预期 = 3。测试访问器和变异器的此属性的好方法是什么?
I am working with a class that has lots of properties. For example;
public class Bib
{
public int PartQty { get; set; }
}
Now to unit test; I did the xUnit test something like
[Fact]
public void CanGetAndSetPartQuantity()
{
const int expected = 3;
var target = new Bib() {PartQty = expected};
Assert.Equal(expected, target.PartQty);
}
here, I hate how I am hard-coding expected = 3. What's a good way to test this property for accessor and mutator?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
由于该属性除了作为整数的 getter/setter 之外没有任何行为,因此您实际上只是在测试编译器是否正常工作。这对您的测试基本上没有任何价值。考虑完全删除它。这会让你摆脱这种奇怪的情况。 :)
如果您确实有一些想要捕获的行为(例如,允许的边界条件),您只需要测试这些行为,实际上不需要其他任何东西。通常,您将拥有作为对象一部分的边界条件常量。考虑使用这些常数,+/-一些适当的增量。
Since this property has no behavior other than being a getter/setter for an integer, you're essentially just testing that the compiler worked. This adds basically no value to your test. Consider removing it entirely. That would alleviate you of this odd situation. :)
If you do have some behavior you're trying to capture (e.g., allowed boundary conditions) you only need to test those, and really nothing else. Usually you will have constants for those boundary conditions available as part of the object. Consider using those constants, +/- some appropriate increment.
约束非确定性非常适合这种单元测试。像这样写:
这可以确保输出正确地表示输入,无论输入是什么。
Constrained Non-determinism is a good fit for this kind of unit test. Write it like this instead:
This ensures that the output correctly represents the input, no matter what the input is.
我坚信单元测试是“白盒”测试,这意味着您可以使用已知的极端情况来选择测试输入。在这种特殊情况下,如果您信任您的编译器,则对于自动属性,测试是不必要的。如果您不能相信编译器会按照您期望的方式实现自动属性,那么您也不能相信它会按照您编写的方式执行测试。
也就是说,如果您有一个更复杂的设置器,您将根据可能的失败情况选择输入。一些典型情况:
I'm a firm believer in having unit tests be 'white-box' tests, which means you are allowed to use known corner cases to choose your test inputs. In this particular, case, with an auto-property, the test is unnecessary if you trust your compiler. If you can't trust the compiler to implement an auto-property the way you expect, then you can't trust it to execute the test as you've written, either.
That said, if you have a more complex setter, you would choose your inputs based on the possible failure cases. A few typical cases:
这应该有帮助...
This should help...
不久前,我观看了关于良好单元测试实践的演示(抱歉,我忘记了那个人的名字)。他主张使用精心选择的名称来存储类似常量的值。
在您的情况下,我会使用像这样的名称
,您表示有意使用该值,在这种情况下,您就在任何有效数量之后。
I wathced a presentation on good unit testing practices a while ago (sorry but the name of the guy escaped my fragile memory). He advocated the use of storing values like that in constants with carefully selected names.
In your case, I would use a name like
By this, you signal the intention of using exactly this value, and in this case you are just after any valid quantity.
测试应该源自某种用例。有趣的是,你首先介绍了你的课程,然后谈论编写测试,这倒退到了 TDD。
用例通知测试,测试通知代码。我非常怀疑您的用例是“我的 API 的用户可以将名为
PartQty
的属性设置为任何整数,并始终取回他们设置的整数”。如果这是真实的用例,您将编写一个单元测试来检查int.MaxValue
和int.MinValue
。然而,这些很少是现实世界的价值观。真实世界的用例可能如下所示:“我的 API 消息的用户在
Bib
上注入IFlugleBinder
,将PartQty
设置为 4然后调用Execute
方法,这将调用IFlugleBinder
实例上的Bind
方法 4 次。”如果这是用例,您的测试看起来会非常不同。老实说,
Bib
看起来只是某种 DTO。根据我的经验,大多数 DTO 只是某些更高级别用例的产物。如果 DTO 作为 API 提供的函数调用的某些结果返回,那么您实际上应该返回一个接口,并且 DTO 类本身应该是私有的,在这种情况下,不需要显式测试它(只需测试属性从方法调用中获得的实际结果)。同样,如果它是从未公开的内部 DTO,则不要将其公开。如果您的用户必须提供一些值,那么您的 API 应该接受一个接口。让用户定义自己的实现该接口的类,或者提供一个不可变的类,如下所示:然后,如果您想学究气,您可以编写一个测试来检查您的构造函数是否有效,但这并不那么重要。
The test should be derived from some kind of use case. The funny thing is that first you introduced your class, then talked about writing a test, which is backwards to TDD.
The use case informs the test, which informs the code. I highly doubt your use case is "the user of my API can set a property called
PartQty
to any integer and always get back the integer they set". If that were the real use case, you'd write a unit test that checksint.MaxValue
andint.MinValue
. However, these are rarely real-world values.A real-world use case might look like: "the user of my API news up a
Bib
injecting anIFlugleBinder
, sets thePartQty
to 4 and then calls theExecute
method. This calls theBind
method on theIFlugleBinder
instance 4 times." If that was the use case, your test would look very different.Honestly it looks like
Bib
is just a DTO of some kind. In my experience, most DTO's are just an artifact of some higher level use case. If the DTO is returned as some result of a function call that your API provides, then you should really be returning an interface, and the DTO class itself should be private, in which case it's not necessary to test it explicitly (just test the properties of the actual result you get from the method call). Likewise, if it's an internal DTO that's never exposed, then don't make it public. If your user has to provide some bundle of values, then your API should be accepting an interface. Let the user define their own class that implements the interface, or provide an immutable one, like this:Then you can write a test that checks if your constructor works if you want to be pedantic, but it's not that important.
虽然我也相信这属于“测试直到无聊”类别,但如果您确实觉得这值得测试,那么批准测试提供了一种非常简单的测试方法。附件是一个简单的测试来检查属性。
这将生成一个文件,内容如下:
只需将该文件重命名为 .approved 即可完成。
请注意扩展方法的使用: .WritePropertiesToString()
这里有一个关于
MsTest 批准测试基础知识的视频: http://www.youtube.com/watch?v=bg8GOmlwqYY
Nunit:http://www.youtube.com/watch?v=aO_fyZBxaFk
Xunit:http://www.youtube.com/watch?v=8wPx0O4gFzc
While I also believe this falls under the "Test till bored" category, if you indeed feel this is worth testing, approval tests offers a very simple way to test. Attached is a simple test to check properties.
This will produce a file that reads:
Simply rename that file to .approved and you're done.
Note the use of the extension method: .WritePropertiesToString()
There a video about the basics of approval tests here for
MsTest: http://www.youtube.com/watch?v=bg8GOmlwqYY
Nunit: http://www.youtube.com/watch?v=aO_fyZBxaFk
Xunit: http://www.youtube.com/watch?v=8wPx0O4gFzc
您也可以使用 autofixture autodata 属性,如下所示:
also you can use autofixture autodata attribute like this: