断言是编程中用于验证代码执行过程中某些条件是否满足的一种机制。在调试过程中,断言能帮助快速定位问题,因为它可以在条件不满足时立即抛出错误,而不需要逐行检查代码。当一个断言失败时,通常会弹出一个断言失败的窗口,允许选择中止、忽略或跳转到断言指令处重试。
例如,假设有如下代码:
private void IKnowForSureThatANullStringWillNeverBePassed(string text)
{
System.Diagnostics.Debug.Assert(text != null, "text is null.");
// ...
}
由于这个方法是私有的,可以完全控制传递给text参数的值,因此断言它永远不会是null。如果text永远不会是null这一点不是很明显,断言还可以作为文档说明。
通常会在调试编译版本上运行单元测试和集成测试,这些断言在断言失败时会使测试失败,而不是运行完方法后抛出一个NullReferenceException。这就是为什么(以及更多的人)编写了这个简单的TraceListener:
public class TraceListener : global::System.Diagnostics.TraceListener
{
public static readonly TraceListener Default = new TraceListener();
protected TraceListener()
{
this.Name = "Testing Trace Listener";
}
protected TraceListener(string name) : base(name)
{
}
public override void Write(string message)
{
}
public override void WriteLine(string message)
{
}
public override void Fail(string message, string detailMessage)
{
var builder = new global::System.Text.StringBuilder();
builder.Append(message);
if (detailMessage != null)
{
builder.Append("\n");
builder.Append(detailMessage);
}
throw new global::Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException(builder.ToString());
}
}
这个TraceListener不会将任何内容写到任何地方。如果调用Fail方法,它只会抛出一个AssertFailedException,这正是断言失败时发生的情况。
在运行测试时(特别是当它们是作为构建过程的一部分自动运行的测试时),不希望出现断言窗口,因此最好在测试项目的配置文件中禁用断言UI。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.diagnostics>
<assert assertuienabled="false" />
</system.diagnostics>
<trace>
<listeners>
<add name="TestTraceListener" type="PauloMorgado.TestTools.VisualStudio.UnitTesting.Diagnostics.TraceListener, PauloMorgado.TestTools.VisualStudio" />
</listeners>
</trace>
</configuration>