编写清晰表达力强的断言

在进行单元测试时,断言是验证代码行为是否符合预期的重要手段。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的检查等。

反馈

如果喜欢这篇文章,请给它评分。任何评论都是欢迎的,例如它是否有用或者改进建议等。谢谢!

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485