Sunday, November 20, 2005

Introducing mock objects in unit testing

The problem is: During unit testing I wish to replace (mock) a certain class (A) that is being used by the class (B) being tested.
The question is: how is this best done?

I can think of three ways:
  1. Inherit B (with class C) and override the (protected) method that loads up A. In C, A-mock would be loaded instead of A. During testing run the unit tests on C instead of B.
  2. Add public or internal methods to B that allow A being set. During testing give B A-mock instead of A using these new methods.
  3. Use reflection to load A dynamically based on the configuration (in app.config, e.g.). During testing replace A with A-mock in the configuration.
All these ways impose some change to the class, B, under test, but what change is most acceptable?

Unfortunately I don't have the answer to that :)

4 comments:

h.tomasson said...

Take a look at the NMock library. It has good examples of creating dynamic(!) mocks and how to introduce them to the class under test. The easiest way to do it is to have a setter method for the mocked object on the class under test. (And you guessed right, we're using jMock :)

Ari said...

Have you tried using reflection or inheriting the class under test? Have you gone through the pros and cons for the different approaches?

P.s. I have been using NMock to generate mock objects and I am very pleased with it.

h.tomasson said...

I haven't used the method of inheriting the class under test because then I might miss out something from the actual class. I think it's better to simply get rid of dependencies with mock objects and run tests on the class itself. (I'm not sure what you mean by using reflection).

Ari said...

I came across this idea of using the configuration (reflection) to substitude an object with its mock object in this article: http://www.theserverside.net/articles/showarticle.tss?id=10WaysTestableCode (see the "Make use of configuration" section).