When using Microsoft CodeContracts your Contract.Requires and Contract.Ensures statements will throw a ContractException which you cannot catch (per design). This means that you cannot use the [ExceptedException] attribute to assert them.

Furthermore when mocking with Telerik Justock you cannot use Contract.Ensures and Contract.Requires at all in your stubs, as the stub is expected to be a Func in the form of .DoInstead(() => { return something; }).

This means when mocking an underlying function in your code to verify your subject under test, you have to come up with a workaround to mimick that behaviour.

Imagine you have the following functions:

public class HelperClass()
{
  public SomeObject HelperFunction(int value)
  {
    Contract.Requires(0 < value);
    Contract.Ensures(null != Contract.Returns<someobject>());</someobject>

    // do something against a backend system not reachable from the test environment
    var result = HttpClientHelper.Get("https://www.example.com/somewhere");
    return new SomeObject(result);
  }
}

public class SutClass()
{
  public bool SutMethod(int value)
  {
    var someObject = new HelperClass().SomeObject(value);
    return someObject.IsValid();
  }
}

In case you want to test your SutClass and HelperClass contains some functionality that you cannot or do not execute within your test environment, your code will fail within the HelperClass and thus your SutMethod cannot be tested like this:

[TestMethod]
public void SutMethodWithInvalidSomeObjectThrows()
{
  // Arrange
  var sut = new SutClass();

  // Act
  var result = sut.SutMethod(42);

  // Assert
  Assert.IsTrue(result);
}

In your test environment your HelperFunction would not throw in Contract.Ensures but already throw while trying to reach the web server. In addition, the exception would probably not be a ContractException but some other exception like WebException.

We can actually bypass this by mocking the SutClass and returning different code that will throw the assertion as expected. We will use Telerik JustMock for this:

[TestMethod]
[ExpectContractException]
public void SutMethodWithInvalidSomeObjectThrows()
{
  // Arrange
  var sutClass = Mock.Create<sutclass>();
  Mock.Arrange(() => sutClass.SutMethod(Arg.IsAny<int>()))
    .IgnoreInstance()
    .DoInstead(() => { Contract.Assert(null != null); });</int></sutclass>

  // Act
  var result = sut.SutMethod(42);

  // Assert
  // no assertion needed as SutMethod is expected to  throw
}

With this mock we can actually simulate the exception thrown by Contract.Ensures as Contract.Assert will throw the same exception.

That was easy and we are already at the end of our story … for more information also have a look about our other post about CodeContracts, the ExpectContractException attribute and Telerik JustMock.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.