Showing posts with label EasyMock. Show all posts
Showing posts with label EasyMock. Show all posts

21.2.12

EasyMock: Verify Arguments

Sometimes, when you are using EasyMock you do not just want to verify the behavior of some class, but also the state of some created objects you actually have no access to. E.g. you are testing a method that builds an object and passes this to your created mock.
EasyMock provides the following possiblity to gain access to these arguments:

    @Test
    public void checkThePassedObject(){
        SomeEJB someEjb = createMock(SomeEJB.class);
        someEjb.timeSomething(anyObject(Timer.class));
        expectLastCall().andAnswer(new IAnswer<Object>() {
            public Object answer() throws Throwable {
                passedTimer = (Timer) getCurrentArguments()[0];
                return null;
            }
        });
       
        replay(someEjb);
        classUT.setSomeEjb(someEjb);
        classUT.createSpecialTimer();
        Assert.assertNotNull(passedTimer);
        verify(someEjb);
    }

The actual magic happens in the anonymous IAnswer class; within the implemented answer method you can do whatever you want. In this case we simply retrieve the passed objects using the getCurrentArguments method. And thats it. Simple as that.

However, if you do not care about your mock behavior at all, how often it is called, what parameters are passed or if it is even called, you can use the andStubReturn method:

SomeEJB someEjb = createMock(SomeEJB.class);
expect(someEjb.removeDigits(not(eq("")))).andStubReturn("no_digits");

In this case, whenever the method is called with a not empty string the mock will return "no_digits".

9.12.11

Mocking-out a Singleton

It may happen that you have to use some legacy Singleton class. And of course you want to create a test double for it, when writing your unit tests.
For this use case, EasyMock is not sufficient, so something stronger is needed: PowerMock. With this testing framework, you can mock-out final classes, static methods, private constructors etc.

Mandatory steps:
  • @RunWith(PowerMockRunner.class) - must be provided on class level
  • @PrepareForTest(MySingleton.class) - also on class level defining the class you want to power-mock
  •  PowerMock.mockStatic(MySingleton.class); -  enables static mocking

The rest of the unit test is done using the EasyMock API, e.g. :

...
import org.powermock.api.easymock.PowerMock;
import static org.easymock.EasyMock.*;

@RunWith(PowerMockRunner.class)
@PrepareForTest(MySingleton.class)
public class ClassUsingSingletonTest {

    @Test
    public void returnsTheSumOfTwoIntegers() throws Exception {
        PowerMock.mockStatic(MySingleton.class);

        MySingleton singletonMock = createMock(MySingleton.class);
        expect(MySingleton.getInstance())   
              .andReturn(singletonMock); 
        expect(singletonMock.doSomeLegacyStuff(anyInt()))
              .andReturn(true);
       
        PowerMock.replay(MySingleton.class);
        replay(singletonMock);

        ClassUsingSingleton classUnderTest =
                    new ClassUsingSingleton();
        int result = classUnderTest.addTwoNumbers(5, 5);
        assertEquals(10, result);
       
        verify(singletonMock);
        PowerMock.verify(MySingleton.class);
    }
}