注意在单元测试中,VSTS自动为你生成了测试的骨架,但是你还是要自己做不少事情,最起码要把那些//TODO的事情给做了(如代码清单11-2所示)。在这个时候,单元测试还都是用的Assert. Inconclusive,表明这是一个未经验证的单元测试。
代码清单11-2
/// <summary> ///A test for User (string) ///</summary> [TestMethod()] public void ConstructorTest() { string userEmail = null; // TODO: Initialize to an appropriate // value
User target = new User(userEmail); // TODO: Implement code to verify target Assert.Inconclusive("TODO: Implement code to verify target"); } |
进行简单的修改后,我们得到了一个如代码清单11-3正式的单元测试:
代码清单11-3
[TestMethod()]
public void ConstructorTest() { string userEmail = "someone@somewhere.com";
User target = new User(userEmail);
Assert.IsTrue(target != null); } //我们还可以进一步测试E-mail是否的确是保存在User类型中。 |
解释单元测试的结构
从上面这个例子可以看到创建单元测试函数的主要步骤:
(1)设置数据(一个假想的正确的E-mail地址);
(2)使用被测试类型的功能(用E-mail地址来创建一个User类的实体);
(3)比较实际结果和预期的结果(Assert.IsTrue(target != null);)。
现在可以运行单元测试了,同时可以看看代码覆盖报告“code coverage report”,代码百分之百地都被覆盖了。
当然这时候的代码还有很多情况没有处理,同学们在台下杂曰——
处理空的字符串,长度为零的字符串,都是空格的串……
小飞熟练地用Copy/Paste又写了下面的三个测试,如代码清单11-4所示。
代码清单11-4
[TestMethod()] [ExpectedException(typeof (ArgumentNullException))] public void ConstructorTestNull() { User target = new User(null); } [TestMethod()] [ExpectedException(typeof(ArgumentException))] public void ConstructorTestEmpty() { User target = new User(""); } [TestMethod()] [ExpectedException(typeof(ArgumentNullException))] public void ConstructorTestBlank() { User target = new User(" "); } |