2009-10-08 98 views
3

我有一个类(很多)有属性。有些人有逻辑,有些则没有。假设我想测试这些属性,我该怎么做呢?如何(策略)以BDD风格对单元测试属性(get/set)进行测试?

最近,我对创建单元测试的BDD风格感兴趣。

参见herehere

所以我会做一个上下文的设置 - 基本上创建SUT并加载任何需要的东西。 然后在每个Observation(测试方法)中,我会验证某个特定属性是否包含它应包含的内容。

这是我的问题。如果SUT有20个属性,那么我是否创建了20个观测/测试?可能更多,如果其中一个属性包含更多有趣的逻辑我猜。

[Observation] 
public void should_load_FirstName() 
{ 
    Assert.Equals<string>("John", SUT.FirstName); 
} 

[Observation] 
public void should_load_LastName() 
{ 
    Assert.Equals<string>("Doe", SUT.LastName); 
} 

[Observation] 
public void should_load_FullName() 
{ 
    Assert.Equals<string>("John Doe", SUT.FullName); 
} 

但是,如果在单一观察中汇总简单的那个,会更好吗?

[Observation] 
public void should_load_properties() 
{ 
    Assert.Equals<string>("John", SUT.FirstName); 
    Assert.Equals<string>("Doe", SUT.LastName); 
    Assert.Equals<string>("John Doe", SUT.FullName); 
} 

或者如果我使用自定义属性(可以多次应用于方法)会怎么样。所以,我可以做的可能,像:

[Observation(PropertyName="FirstName", PropertyValue="John")] 
[Observation(PropertyName="LastName", PropertyValue="Doe")] 
[Observation(PropertyName="FullName", PropertyValue="John Doe")] 
public void should_load_properties() 
{ 
} 

回答

4

一般来说,你应该为每个测试只有一个逻辑肯定之后努力。优秀的书xUnit Test Patterns包含了一个很好的讨论,但重要的是,如果只有一个测试失败的原因,它可以更容易地理解违规发生的位置。这可能回归测试比BDD,但更多的相关...

所有这一切都意味着你编写一个测试验证所有属性的选项可能是最有吸引力的,尽管你可以认为所有验证属性是一个逻辑断言...

xDD(TDD,BDD,无论)的更中心原则是测试应该充当可执行规范。换句话说,当你看看测试不仅什么正在测试,而且为什么的预期值是这样,它应该立即显而易见。在你的例子中,不太清楚为什么SUT.FirstName预计会是“John”而不是“Jane”。

如果可能的话,我会写这些测试以使用Derived Values而不是硬编码的值。

对于可写属性,我经常编写简单的验证getter函数返回分配给setter的值的测试。

前面的只读属性,我经常写测试,验证值匹配构造函数参数。

这样的测试可以封装成封装常用测试用语的可重用测试代码。我目前正在致力于library that can do just that

+0

感谢马克的建议。回来的时候,你的CallContext博客文章帮了我很多! 我跟随了Meszaros网站上Derived Values的链接并阅读了它(在你的网站之后)。我不确定我会像实施逆向示例一样去实现它的极限。我认为在输入旁边有一个变量expectedResult,然后使用文字值。 在我上面的例子中,我听到你 - 这并不明显,但我从本地磁盘加载测试数据来创建SUT(这是一个验收/交互测试)。我需要找到更好的方法来指定输入值... – 2009-10-09 13:30:50

0

查看其他SubSpec语法([Specification]示例) - 在这种情况下,末尾的每个Assert代表测试的单独执行。我原来打折的lambda滥用的语法,但现在我一直在使用它。