我想编写单元测试来验证我的方法不接受无效参数。使用Code Contract的Contract.Requires
调用检查参数的有效性。我为什么要测试合同?我认为我的测试是一种方法规范(实际上是从TDD中获取的),所以通过测试方法对某些参数失败,我指定不应该使用这些参数。
问题在于,由于我开始使用代码契约,因此无法测试方法契约,因为我无法访问Contract.Requires
引发的异常。我可以捕获泛型Exception
,但这并不好......有没有推荐/支持的方法如何使用代码合同测试合同集?
在我看来,Code Contracts并不真正支持单元测试...
编辑:我的测试示例(我被迫捕获一般异常)
[ExpectedException(typeof(Exception), AllowDerivedTypes = true)]
public void Compute_Throws_ForNullArgument()
{
new ComputingService().Compute(null);
}
答案 0 :(得分:3)
您可以加入Contract.ContractFailed
事件。
这将在抛出异常之前引发。您可以将此与捕获Exception
结合起来,以确定它代表合同失败
public void VerifyContract(Action action) {
bool failed = false;
bool thrown = false;
EventHandler e = (sender, e) => { failed = true; }
Contract.ContractFailed += e;
try {
action();
} catch (Execption) {
Assert.True(failed);
thrown = true;
} finally {
Contract.ContractFailed -= e;
}
Assert.True(thrown);
}
答案 1 :(得分:2)
您无法显式捕获正确的异常类型,但您可以捕获Exception
,然后使用反射检查它是ContractException
(否则重新抛出)。
在到处这样做会很难看,但你只需要做一次:
public static void AssertContractFailure(Action action)
{
try
{
action();
Assert.Fail("Expected contract violation");
}
catch (Exception e)
{
if (...) // I can't remember offhand what you'd need to check
{
throw;
}
}
}
然后:
AssertContractFailure(() => SomeContractViolation(...));
目前,如果您在帮助程序类中拥有该程序,则需要在任何地方限定呼叫,但从C#6起,您希望能够轻松导入它:)
答案 2 :(得分:0)
如果我没记错的话,如果Requires
构造失败,并且Return
构造失败,则合同会抛出异常。因此,对于单元测试目的,您只需要捕获这些异常,并且您将知道合同是否被违反。