Jun 29, 2009

Refactory to break dependency

  • Extract an interface to allow replacing underlying implementation
  • Inject stub implementation into a class under test
  • Receiving an interface at the constructor level.

    If your code under test requires more than one stub to work correctly without dependencies, adding more and more constructors ( or more and more constructor parameters) becomes a hassle, and it can even make the code less readable and less maintainable. One possible solution is using inversion of control containers. You can think of IoC containers as "smart factories" for you objects. A container provide special factory methods that take in the type of object you'd like to create and any dependencies that it needs, and then initialize the object using special configurable rules such as what constructor to call, what properties to set in what order, and so on. They are powerful when put to use on a complicated composite object hierarchy where creating an object requires creating and initializing object serveral levles down the line. Using constructor arguments to initialize objects can make you testing code more cumbersome unless you're using helper frameworks such as IoC containers for object creation. Every tie you add another dependency to the class under test, you have to create a new constructor that takes all other arguments plus a new one, make sure it calls the other constructors correctly, and make sure other users of this class initialize with the new constructor.

    On the other hand, using parameters in constructors is a great way to signify to the user of your API that these parameters are non-optional. They have to be sent in when creating the object.

    If you want these dependencies to be optional, use properties, which is much more relexed way to define optional dependencies adding different constructors to the class for each dependency. If you choose to use constructor injection, you'll probably also want to use IoC containers. This would be a great solution if all code in the world were using IoC, containers. The future of unit testing will use more and more of these Ioc pattern.

  • Receive an interface as a property get or set.

    Use this technique when you want to signify that a dependency of the class under test is optional, or if the dependency has a default instance created that doesn't create any problems during the test.

  • Get a stub just before a method call