2014-09-04 29 views
1

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

但是,我一直无法创建一个测试来覆盖这种情况,因为Contract.Requires首先失败会导致一个ContractException。我希望能够仅针对此特定测试禁用运行时合约。

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

代码示例(不是真正的生产代码,但应说明什么,我试图做):

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 
} 
+0

请显示一些代码。我认为你应该使用'Contract.Requires (...)',但我不能确定没有看到代码。 – 2014-09-04 08:50:20

+0

'Contract.Requires (...)'不是我们在我们的环境中使用的模式。我们使用'Contract.Requires(...)'调用,其中不建议使用您建议的调用。 – Xilconic 2014-09-04 09:05:47

回答

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; 
    } 
} 

如果用代码契约重写确保你有“断言失败”未选中如果你想抛出你的异常。

+0

是的,但那样我就会测试我甚至没有实施自己的合同。这只适用于实际启用了运行时代码合同检查的人员。例如,测试在发布模式下运行时会失败。 – Xilconic 2014-09-04 09:17:39