Guidelines to using Interaction Based Testing

time to read 2 min | 385 words

One of the major differences between interaction based and state based testing is the level that you are testing the code. State based testing is testing results of an operation, interaction based testing tests the operation itself. This means that you can get into situations where you are atrophied by the tests. Any change to the code causes a cascading affect on all the tests.

Here are some guidelines that should help in this regard. They all boil down to "A Test Should Check Only One Thing". This means that we need a distinction here. We have fake objects, which are created just so we can give the test the data it needs. And then we have mocks, which are used to verify the behavior of the test.

In general, there should be as few mocks as possible, preferably one. All the other collaborators should be fakes.

To clarify, both mocks and fakes can be had from a mocking framework, I am not making the distinction about how they are created, only how they are used.
Fake Object - needed for the test to pass, operations on it are not important.
Mock Objects - what we are verifying in the test, operations on it are what we are testing.

For mock objects, you should use the full power of the mocking framework to setup detailed expectations about what should happen. For fake objects, you should make sure that as much as possible, they will not break the tests.

For Rhino Mocks, this means that fake objects should:

  • Prefer to use DynamicMock over CreateMock
  • Use SetupResult over Expect or LastCall

Using both of those should reduce the number of expectations that the test should meet. Remember a test should have only one thing that can fail it.