Some Examples
The Collaborator
The premise of a collaborator is that it is an object that collaborates with another object for some purpose. Usually this is a dependency of some sort. Now, you can have a collaborator that is injected into the target object by some form of dependency injection, or it is created by the target object. Either way, you need to be able to mock the behavior of this collaborator object. The latter approach is much harder to test because you are doing a createObject() call. However, you need to put into practice your testable and refactor skills to work, in order to make this more testable. Thanks Marc Esher!
Example:
The source above is too hard to test because you have no control over the create object call. Therefore you can have two solutions for this, which actually makes your code more testable.
Have a method return to you an instance of the Validator object.
Have the Validator object be injected via dependency injection into your target object.
Most of the time collaborators can be injected by dependency injection, but sometimes they will not as they are only in use by the target object. So let's do both approaches, starting with dependency injection via annotations: cfproperty.
Now that we have a annotation injection or a setter injection, let's mock the collaborator into our target object with the mocked method for isValid email.
There you go. Now let's refactor our method call:
As you can see, even our method look cleaner and sharper thanks to our refactoring. However, the most important aspect of our refactoring is that now we can mock the collaborator.
Method Spies
The premise of method spies is that you want to mock the return of method calls inside the target object that we are testing because these methods are helper methods. Also, maybe these helper methods have an access type of private which we cannot mock directly. Here is a typical example in one of my security objects:
Ok, this simple liner security validator throws tons of problems. Why? Well, I have three internal private calls:
getUserSession() - supposed to return a nice user object
isSSOCookieValid() - checks if a single sign on cookie is set
authorizeUser() - Authorize a user in my system
Since I am unit testing this target object's userValidator
method, I don't really care about the method calls, I just worry about the behavior that is associated with them because my other tests will go into detail about what they do. However, for my purposes of testing the userValidator
method, I just need behavior. Thus, we need to be able to create mocking representations of these methods.
As you can see from the example above, I mocked all the necessary data and objects to test all the paths that I could follow in my userValidator
method. Now we are cooking with MockBox.
Last updated