暂时禁用代码合同

时间:2014-09-04 08:33:25

标签: c# code-contracts

代码合同允许在接口上定义合同,例如IList<T>。其中一些,如前面提到的那些,已经在.Net中实现了这些。我正在创建一个继承自IList<T>的类,并且我正在编写测试以覆盖错误条件,例如错误地使用索引器(根据接口规范,期望ArgumentOutOfRangeException)。

但是,由于Contract.Requires首先导致ContractException,因此我无法创建测试来覆盖此场景。我希望能够仅针对此特定测试禁用运行时合同。

这可能吗?我在我的测试中已经尝试过ContractVerificationAttribute(false),但是这不起作用(我希望它会r到它内部调用的所有方法,但事实并非如此)。

代码示例(不是真正的生产代码,但应说明我尝试做的事情):

class A : IList<object> {
    private IList<object> list = new List<object>();

    // All other implementation code

    public object this[int index]
    {
        get { return list[index]; }
        // The setter I want to check
        set
        {
            if (index < 0 || index >= Count)
            {
                 throw new ArgumentOutOfRangeException("index");
            }
            list[index] = value;
        }
    }
}

[Test]
public void TestSettingAtIndexOutsideListThrowsException(){
    try {
        A a = new A();
        a[0] = new object();
        // Some method to fail the test
    }
    catch(ArgumentOutOfRangeException e)
    {
         // Check if 'e' is what you expect. If not, fail the test. If it is, pass it.
    }
 // Some method to fail the test
}

1 个答案:

答案 0 :(得分:0)

据我所知,没有办法压制异常。但是,您可以捕获异常,检查类型的全名并吞下ContractException(https://stackoverflow.com/a/2640011/1494550)。

看到代码会很好,因为可能有某种方法可以在不触发ContractException的情况下生成错误条件。

<强>更新

在检查错误后查看了要放置Contract.EndContractBlock的代码:

public object this[int index]
{
    get { return list[index]; }
    // The setter I want to check
    set
    {
        if (index < 0 || index >= Count)
        {
             throw new ArgumentOutOfRangeException("index");
        }
        Contract.EndContractBlock();
        list[index] = value;
    }
}

如果使用代码合同进行重写,请确保在发生故障时“断言”&#39;如果您希望抛出异常,则取消选中。