views:

7054

answers:

3

I have a method that returns void in a class that is a dependency of the class I want to test.

This class is huge and I'm only using this single method from it. I need to replace the implementation of this method for the test as I want it to do something different and I need to be able to access the parameters this method receives.

I cannot find a way of doing this in EasyMock. I think I know how to do it with Mockito by using doAnswer but I don't want to add another library unless absolutely necessary.

A: 

In situations like these I've found that making a nested class in my unit test class and overriding the methods with special requirements in that way is the best route. So if you're testing ClassA which has that method with the parameters you need to access, you'd do something like:

class MockClassA extends ClassA {
    @Override
    void specialMethod(String param1, String param2) {
        // do logging or manipulation of some sort
        super.specialMethod(param1,param2); // if you need to
    }
}

In my unit testing code, I then just use this instance instead. Just treat it as if it was any other mock object. Much easier than mixing libraries, which I agree is probably not a good idea.

Marc W
Already considered it. But it is an abstract class, so I would need to provide like 20 empty method implementations or subclass one of its children, which could be a bit confusing for other developer looking at the test.
Iker Jimenez
Oh okay. I didn't know it was abstract. If you're using an IDE (I'm assuming you're using Eclipse or NetBeans), it can pull all those abstract methods in for you and you can just stick a comment above them all explaining what you're doing. Not a very programmatic solution, but at least other developers won't be confused by it.
Marc W
+10  A: 

If I understand what you want to do correctly, you should be able to use andAnswer():

mockObject.someMethod(eq(param1), eq(param2);
expectLastCall().andAnswer(new IAnswer() {
    public Object answer() {
        //supply your mock implementation here...
        SomeClass arg1 = (SomeClass) getCurrentArguments()[0];
        AnotherClass arg2 = (AnotherClass) getCurrentArguments()[1];
        arg1.doSomething(blah);
        //return the value to be returned by the method (null for void)
        return null;
    }
});

Javadoc on IAnswer

matt b
That's exactly what I wanted, thanks a million. I find that part of the API a bit confusing anyway, compared to what I've seen in another mocking frameworks.
Iker Jimenez
I think the Easymock documentation could definitely use some work on pointing out that these types of things are available - it's not the most comprehensive.
matt b
+2  A: 

If you just call the void method for each time you're expecting it to be invoked and then invoke EasyMock.expectLastCall() prior to calling replay(), Easymock will "remember" each invocation.

So I don't think you need to explicitly call "expect()" (other than lastCall) since you're not expecting anything from a "void" method, except its invocation.

Thanks Chris!

Here's a good blog post that provides more detail: http://burtbeckwith.com/blog/?p=43

eqbridges
I think this answer doesn't address the question - he doesn't want to just assert an expectation on the method, but also replace it's implementation.
matt b