在进行单元测试时,断言是验证代码行为是否符合预期的重要手段。Visual Studio提供了一套断言类,如Assert和StringAssert,它们包含了一些特定的方法来断言某些条件。然而,如何正确地使用这些断言方法,以确保断言既简洁又具有表达力,是一个挑战。本文首先介绍了编写简洁且表达力强的断言的指导原则,然后探讨了现有Assert类的限制,并提出了如何克服这些限制的建议。
断言类提供了一些特定的方法来断言某些条件。应用断言时的挑战在于,需要调用适当的断言方法,这些方法能够报告预期和实际的值,并提供一个有意义的断言消息,同时避免重复格式化消息的诱惑。
例如,以下断言应该被重写:
if (list.Count != 6)
{
Assert.Fail("Error: list.Count = {0}", list.Count);
}
重写后的断言如下:
Assert.AreEqual(6, list.Count, "Error: list.Count = {0}", list.Count);
最终的断言应该像这样:
Assert.AreEqual(6, list.Count, "wrong number of xxx");
这种断言是理想的:使用了适当的方法来报告值,消息简洁且未格式化,没有多余的注释。
那么,如何断言以下情况:
list.Count > 4
没有像Assert.Greater(...)这样的函数。最接近的是之前提到的Assert.IsTrue(...)。例如:
Assert.IsTrue(list.Count > 4, "too little xxx elements");
结果消息是:
Assert.IsTrue failed. too little xxx elements
没有提到预期和实际值,也没有提到应用了哪种检查...
因此,回到注释和格式化消息?例如(这不是推荐):
Assert.IsTrue(list.Count > 4, "xxx list has only {0} elements instead of more than 4 elements", list.Count);
结果消息是:
Assert.IsTrue failed. xxx list has only 1 elements instead of more than 4 elements
提供的代码中包含了一个ExtAssert类,它提供了四个缺失的函数:
public static void Greater(T a, T b, string message, params object[] args) where T : IComparable
public static void GreaterOrEqual(T a, T b, string message, params object[] args) where T : IComparable
public static void LessOrEqual(T a, T b, string message, params object[] args) where T : IComparable
public static void Less(T a, T b, string message, params object[] args) where T : IComparable
使用这些,可以按照指导原则重写关系断言:
ExtAssert.Greater(list.Count, 4, "too little xxx elements");
结果消息是:
Assert.AreEqual failed. Expected:<(a > b)>. Actual:<(1 < 4)>. too little xxx elements
概念相当简单:定义一个"ok"字符串,例如"(a > b)",提供一个检查函数,如果检查通过则返回"ok"字符串,如果失败则返回实际值关系,例如"(a > b)"与"(1 < 4)",比较检查结果与"ok"字符串:
Assert.AreEqual(ok, check, ...)
这个概念在附带的代码中实现了关系断言的情况。可以按照ExtAssert中所示扩展断言,例如对NullOrEmpty的检查等。
如果喜欢这篇文章,请给它评分。任何评论都是欢迎的,例如它是否有用或者改进建议等。谢谢!