| The Concept of Mocking |
Not all code is self containedWhen we learn to program, our objects are usually self contained. Any hello world has no dependencies on outside classes (System.out aside) and neither do many of the other classes we write in the process of learning a language. However, in the real world, software has dependencies. We have action classes that depend on services and services that depend on data access objects (DAOs) and the list goes on. The idea of unit testing is that we want to test our code without testing the dependencies. This test allows you to verify that the code being tested works, regardless of it's dependencies. The theory is that if the code I write works as designed and my dependencies work as designed, then they should work together as designed. The code below would be an example of this:
import java.util.ArrayList;
public class Counter {
public Counter() {
}
public int count(ArrayList items) {
int results = 0;
for(Object curItem : items) {
results ++;
}
return results;
}
}
I know the above example is about as simple as you get, but it illustrates the point. If you wanted to test the method Now let's look at a slightly more realistic example. Let's consider the code below:
public class MichaelsAction extends ActionSupport {
private LookupService service;
private String key;
public void setKey(String curKey) {
key = curKey;
}
public String getKey() {
return key;
}
public void setService(LookupService curService) {
service = curService;
}
public String doLookup() {
if(StringUtils.isBlank(key)) {
return FAILURE;
}
List results = service.lookupByKey(key);
if(results.size() > 0) {
return SUCCESS;
}
return FAILURE;
}
}
If we wanted to test the Enter Mock Objects
The concept behind mock objects is that we want to create an object that will take the place of the real object. This mock object will expect a certain method to be called with certain parameters and when that happens, it will return an expected result. Using the above code as an example, let's say that when I pass in 1234 for my key to the How Mock Objects WorkThere are many different mocking frameworks in the Java space. I am not going to discuss any of them in great detail here. However, I will discuss how they work and design considerations you need to take in mind because of their implementations. There are essentially two main types of mock object frameworks, ones that are implemented via proxy and ones that are implemented via class remapping. Let's take a look at the first (and by far more popular) option, proxy.
A proxy object is an object that is used to take the place of a real object. In the case of mock objects, a proxy object is used to imitate the real object your code is dependent on. You create a proxy object with the mocking framework, and then set it on the object using either a setter or constructor. This points out an inherent issue with mocking using proxy objects. You have to be able to set the dependency up thru an external means. In other words, you can't create the dependency by calling
The second form of mocking is to remap the class file in the class loader. The mocking framework jmockit is the only framework I am aware of that currently exploits this ability for mock objects. The concept is relatively new (since JDK 1.5 although jmockit supports jdk1.4 thru other means as well) and is provided by the new ConclusionMock objects are a very valuable tool in testing. They provide you with the ability to test what you write without having to address dependency concerns. 9 ResponsesAdd your own comment... |
short and sweet
Shouldn't it be java.lang.Instrument? It says Insturment.
hi,
nice introduction, but I guess you've never heard of jeasytest, which is neither proxy- nor instrument-based and can do magic as well. :) It uses AspectJ.
BTW, there are probably more aspect-based solutions (jeasytest, amock) than instrumentation-based (jmockit only AFAIK), so part of your post in which you divide mocking framework into "proxy" and "instrumentation" is far from truth.
There are also other ways of dealing with such code. I've devoted a whole serie of posts to the problem of testing code which uses "new" or static code calls - see here http://kaczanowscy.pl/tomek/?q=node/66
cheers
Tomek Kaczanowski
Excellent explanation in simple terms !!
Nice and quick introduction to the problematics. Thanks!
I really enjoyed it, congratulations!
Good artical about mocking i started working recently.
I need help with mocking
If you are free then Can you please contact me by e-mail
Regards,
Chirag
Hi
Your blog seems very nice.
Since you encouraged lot to ask questions, here I am. :)
I am new to unit testing tools.
Question: Is it possible to test a servlet using PowerMock? If yes, would you be kind enough to provide a tutorial for the same?
Thanks a lot for your time and help. (in advance)
-B
Nice. Nice.. Nice...