1

Code Contracts allow for contracts to be defined on interfaces, such as IList<T>. Some of these, like the a fore mentioned one, have these implemented in .Net already. I'm creating a class that inherits from IList<T> and I'm writing tests to cover the error conditions such as using the indexer incorrectly (where an ArgumentOutOfRangeException is expected as per the interface specification).

However, I've been unable to create a test to cover this scenario, as a Contract.Requires fails first causing a ContractException. I would like to be able to disable runtime contracts only for this particular test.

Is this possible? I've tried ContractVerificationAttribute(false) on top on my test, but this does not work (I was hoping it would ripple though to all methods called inside it, but this is not the case).

Code Example (Not real production code, but should illustrate what I'm trying to do):

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
}
Xilconic
  • 3,785
  • 4
  • 26
  • 35
  • Please show some code. I think you should be using `Contract.Requires( ... )` but I can't say for sure without seeing code. – Matthew Watson Sep 04 '14 at 08:50
  • `Contract.Requires(...)` is not a pattern that we use in our environment. We use the `Contract.Requires(...)` calls, where mixing in the one you suggest is not recommended. – Xilconic Sep 04 '14 at 09:05

1 Answers1

0

As far as I know there is no way to supress the exception. You can however catch Exception, check the full name of the type and swallow the ContractException (https://stackoverflow.com/a/2640011/1494550).

It would be good to see the code as there may be some way to generate the error condition without firing off the ContractException.

Update

Having looked at the code you want to place Contract.EndContractBlock after checking for errors:

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

If rewriting with Code Contracts make sure you have 'Assert on failure' unchecked if you want your exception to be thrown.

Community
  • 1
  • 1
Alan Bradbury
  • 128
  • 2
  • 8
  • Yes, but that way I would be testing the contract that I didn't even implement myself. And that would only work for people who actually have Runtime CodeContracts checking enabled. For example, the test would fail when run in Release mode. – Xilconic Sep 04 '14 at 09:17