正如Henk所指出的那样,抑制UI是无用的,因为你想让你的代码失败。当你不想改变你的代码时,你可以编写一个自定义跟踪侦听器,抛出异常,如下所示:
public class ProductionTraceListener : DefaultTraceListener
{
public override void Fail(string message, string detailMessage)
{
string failMessage = message;
if (detailMessage != null)
{
failMessage += " " + detailMessage;
}
throw new AssertionFailedException(failMessage);
}
}
[Serializable]
public class AssertionFailedException : Exception
{
public AssertionFailedException() { }
public AssertionFailedException(string message) : base(message) { }
public AssertionFailedException(string message, Exception inner)
: base(message, inner) { }
protected AssertionFailedException(SerializationInfo info,
StreamingContext context) : base(info, context) { }
}
您可以按照以下方式进行注册:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.diagnostics>
<trace>
<listeners>
<clear />
<add name="Default"
type="[Namespace].ProductionTraceListener, [Assembly]" />
</listeners>
</trace>
</system.diagnostics>
</configuration>
如你所料,从跟踪侦听器的名称
ProductionTraceListener
可以看出,我在生产环境(Web 应用程序)中使用它,而不是在单元测试中使用。虽然您可以在单元测试中使用此技巧,但我建议您更改代码。在我看来,你应该只为永远不会运行的代码路径使用断言,如果它们确实运行了,则测试应该失败。在您的情况下,当断言失败时您希望有一个成功的测试,这是反直觉的。
我的建议是更改代码并使用常规的
if (x) throw ArgumentException()
检查前提条件(或使用
CuttingEdge.Conditions),并仅将这些断言用于永远不应运行的代码路径。同时,请尝试使用
Trace.Assert
而不是
Debug.Assert
,因为您也希望这些断言在生产环境中得到检查。当您完成后,您可以在生产环境中使用
ProductionTraceListener
,而在单元测试中使用此
UnitTestTraceListener
。
public class UnitTestTraceListener : DefaultTraceListener
{
public override void Fail(string message, string detailMessage)
{
string failMessage = message;
if (detailMessage != null)
{
failMessage += " " + detailMessage;
}
Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Fail(
failMessage);
}
}
祝你好运。
Trace.Assert
的原因。在调试版本中表现不同是一件坏事。我认为我们对此有相同的看法。 - Steven