Testing With EasyMock
This is more of a reference for me than anything else. But if you find it useful or want to add something, let me know.
There are 6 steps to testing a class with EasyMock.
1. Mock the class
2. Set expectation
3. Replay result
4. Execute testing method/function
5. Verify mock objects
6. Verify the result
So suppose I have the following class
public class Bakery{
protected MyOven oven;
public Bakery(){
oven = new MyOven();
}
public CookedFood cook(Ingredient ingredient) throws OvenException{
CookedFood cookedFood = oven.bake(ingredient);
}
}
(Yes, I'm obviously very creative with my naming scheme.)
Looking at this class, it's obvious that you want to mock out MyOven. But you also want to control what the the oven is returning, so you would also want to mock CookedFood.
Here's the sample code of how I would test the class.
public class BakeryTest{
private MyOven mockOven;
private Bakery bakery;
@Before
public void setUp(){
bakery = new Bakery();
mockOven = EasyMock.createMock(MyOven.class); //1. Create a mock object of the class you want to control
bakery.oven = mockOven; //Tell bakery to use your mockOven.
}
@After
public void tearDown(){
bakery = null;
mockOven = null;
}
@Test
public void testCook(){
CookedFood cookedFood = getCookedFood("cookie");
EasyMock.expect(mockOven.cook(isA(Ingredient.class)).andReturn(cookedFood).anyTime(); //2. Set expectation
EasyMock.replay(mockOven); //3 replay object
CookedFood actual = Bakery.cook(ingredient); //4 Execute testing method
verify(mockOven, cookedFood); //5. Make sure it was actually using your object
Assert.equals(actual.getType
}
@Test(expected=MyOvenException.class)
public void testCookWithException{
EasyMock.expect(mockOven.cook(isA(Ingredient.class)).andReturn
}
//I'm creating a CookedFood object here. You can mock the class or just create a new instance of it, it doesn't matter.
private CookedFood getCookedFood(String type){
CookedFood cookedFood = new CookedFood();
cookedFood.setType(type);
return cookedFood;
}
//Or you can mock the object. It really depends on how much you trust the object. I generally don't, so I use this.
private CookedFood getCookedFood(String type){
CookedFood cookedFood = EasyMock.createMock(CookedFood.class); //1. Mock the class
EasyMock.expect(cookedFood.getType()).andReturn(type).anyTime(); //2. Set expectation
EasyMock.replay(cookedFood); //Replay the mock class
}
}
Note1: The regular EasyMock can only mock interfaces. But if you want to mock an impl, use easymockextension. I generally use easymockextension for everything. When the easymockextension doesn't have a method that I want (e.g. verify), then I use the regular EasyMock. (Look at my import to see.)
Note2: I'm using JUnit 4. That's why I'm using annotation (@Test) instead of extending TestCase.
Note3: The way I do things is not the standard. I don't know what the standard is. If you do know, please point me to that direction.