当然,如果这些属性改变了,我们需要获取到属性改变通知:
[TestMethod]
public void Person_IsChanged_Property_Change_Notification_By_Setting_FirstName() { var person = new Person("Adam", "Smith"); var eventAssert = new PropertyChangedEventAssert(person); person.FirstName = "Bob"; eventAssert.Expect("IsChanged"); } [TestMethod] public void Person_FullName_Property_Change_Notification_By_Setting_FirstName() { var person = new Person("Adam", "Smith"); var eventAssert = new PropertyChangedEventAssert(person); person.FirstName = "Bob"; eventAssert.SkipEvent(); //this was IsChanged eventAssert.SkipEvent(); //this was FirstName eventAssert.Expect("FullName"); } |
接下来两个测试针对HasErrors这个属性和ErrorsChanged事件。
[TestMethod]
public void Person_FirstName_Set_HasErrorsIsFalse() { var person = new Person("Adam", "Smith"); person.FirstName = "Bob"; Assert.IsFalse(person.HasErrors); } [TestMethod] public void Person_FirstName_Set_ErrorsChanged_Did_Not_Fire() { var person = new Person("Adam", "Smith"); var errorsChangedAssert = new ErrorsChangedEventAssert(person); person.FirstName = "Bob"; errorsChangedAssert.ExpectNothing(); } |
目前我们有8个测试了,这意味着当我们修改FirstName的属性值,我们要考虑会发生改变的每件事。但是这不算完。我们还需要确保没有别的会被意外改变。理论上说,这意味着更多的断言和相当数量的测试,但是,接下来我们采用取巧的方法,用ChangeAssert方法来替代HasErrors测试。
[TestMethod]
public void Person_FirstName_Set_Nothing_Unexpected_Changed() { var person = new Person("Adam", "Smith"); var changeAssert = new ChangeAssert(person); person.FirstName = "Bob"; changeAssert.AssertOnlyChangesAre("FirstName", "FullName", "IsChanged"); } |
ChangeAssert简单地通过映射获取对象的状态,因此,稍后你可以断言到除了你指出的几个具体属性其他的没变。
恭喜,你完成了你的第一个测试用例。完成一个,还有很多很多等着。
为什么说是“一个”测试用例?
那8个测试只是完成了覆盖FirstName属性从“Adam”修改成“Bob”这一个场景,在其他的值没有在错误状态、LastName不为null或空的情况下。让我们看看测试用例的完整清单:
1、将FirstName值设置为“Adam”
2、将FirstName值设置为null
3、将FirstName 设为空串
4、在LastName值为null的情况下,执行case1-3
5、在LastName 为空串的情况下,执行case1-3
6、在FirstName值以null开头的情况下,执行case1-5
7、在FirstName值以空串开头的情况下,执行case1-5
目前我们看到了27个不同的场景。如果每个场景需要8个不同测试,仅仅为这一个属性,我们需要执行至多216个测试。根据这种思路,这是相当琐碎的一段代码。因此我们该怎么做呢?