ChangeAssert简单地通过映射获取对象的状态,因此,稍后你可以断言到除了你指出的几个具体属性其他的没变。
恭喜,你完成了你的第一个测试用例。完成一个,还有很多很多等着。
为什么说是“一个”测试用例?
那8个测试只是完成了覆盖FirstName属性从“Adam”修改成“Bob”这一个场景,在其他的值没有在错误状态、LastName不为null或空的情况下。让我们看看测试用例的完整清单:
●将FirstName值设置为“Adam”
●将FirstName值设置为null
●将FirstName 设为空串
●在LastName值为null的情况下,执行case1-3
●在LastName 为空串的情况下,执行case1-3
●在FirstName值以null开头的情况下,执行case1-5
●在FirstName值以空串开头的情况下,执行case1-5
目前我们看到了27个不同的场景。如果每个场景需要8个不同测试,仅仅为这一个属性,我们需要执行至多216个测试。根据这种思路,这是相当琐碎的一段代码。因此我们该怎么做呢?
测试也有代码味道
回看第一个测试用例的8个测试,它们都有同样的设置和运算。唯一的不同是我们写的断言。在业界这个被称为一个代码味道。事实上,根据维基百科所列的这里应该有两个代码味道:
●Duplicated code
●重复的代码
●Excessively long identifiers
●过长的标识符
我们可以通过将断言合并到一个测试来轻松地消除这两个代码味道:
[TestMethod]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public void Person_FirstName_Set() { var person = new Person( "Adam" , "Smith" ); var eventAssert = new PropertyChangedEventAssert(person); var errorsChangedAssert = new ErrorsChangedEventAssert(person); var changeAssert = new ChangeAssert(person); person.FirstName = "Bob" ; Assert.AreEqual( "Bob" , person.FirstName, "FirstName setter failed" ); Assert.AreEqual( "Bob Smith" , person.FullName, "FullName not updated with FirstName changed" ); Assert.IsTrue(person.IsChanged, "IsChanged flag was not set when FirstName changed" ); eventAssert.Expect( "IsChanged" ); eventAssert.Expect( "FirstName" ); eventAssert.Expect( "FullName" ); errorsChangedAssert.ExpectNothing( "Expected no ErrorsChanged events" ); changeAssert.AssertOnlyChangesAre( "FirstName" , "FullName" , "IsChanged" ); } |