I have a problem with Mockito.
Is it possible to do such a thing:
ClassX x = mock(ClassX.class)
when(x.methodB()).thenReturn("toto");
String result = x.methodA();
I'm working with Mockito 1.7.
I saw there was a "spy" system but they say it's not recommended to use it (why?) on the item we test...
I tried that spy function anyway but i get a strange behaviour.
Check what i want to do:
Real code:
String methodA(String arg) {
return this.methodB(arg);
}
String methodB(String arg) {
return "toto";
}
Test code:
@Test
public void testTest() {
final ClassX x = spy( new ClassX() );
final String argument = "arg";
doReturn("good").when(helper).methodB(argument);
assertTrue( x.methodB(argument).equals("good") );
assertTrue( x.methodA(argument).equals("good") );
}
As they said i avoided the when thenReturn syntax that could be a problem with a spy (but it doesn't work either anyway)
The strange thing is that: assertTrue( x.methodB(argument).equals("good") ); is OK
Only the second assertTrue( x.methodA(argument).equals("good") ); is not OK
Actually helper.methodA(argument) returns "toto" -> the real result and not the mock result
It isn't possible to tell mockito to return "good" in this case??? It seems when the test class call methodB it's ok, but if a method of the spy calls the methodB it doesn't work anymore...
I don't know what to do... is it such a strange thing to unit-test 2 methods of the same class and make the tests independent from each others so that a famous mock-test framework doesn't implement this basic function? Isn't it what we just call real unit-testing? Don't understand why they say to avoid using spy method on the tested object...
Thanks
UPDATE: I wrote the stuff below, and then moments later discovered .thenCallRealMethod() which allows you to effectively perform partially stubbing. Mockito authors recommend you use refactoring to separate dependencies into different classes; but they do provide the means to partially stub. I have added a test method to demonstrate this approach, and leave my original comments.
ORIGINAL: I really like Mockito, but this is the one place where EasyMock wins out. I have two solutions for you that don't involve Mockito. The first is to override methodB on your testing instance. The other is to partially mock with EasyMock:
import org.junit.Test;
import static org.junit.Assert.*;
import static org.easymock.EasyMock.*;
public class PartialMockTest {
class ClassX {
String methodA(String arg) {return methodB(arg);}
String methodB(String arg) {return "toto";}
}
@Test
public void MockitoOnClassX(){
ClassX classx = mock(ClassX.class);
when(classx.methodB("hiyas")).thenReturn("tomtom");
when(classx.methodA(anyString())).thenCallRealMethod();
String response = classx.methodA("hiyas");
assertEquals("tomtom",response);
}
@Test
public void OverrideOnClassX() {
ClassX classx = new ClassX(){@Override String methodB(String arg){return "tomtom";}};
String response = classx.methodA("hiyas");
assertEquals("tomtom",response);
}
@Test
public void PartialMockOnClassX() throws NoSuchMethodException {
ClassX classx = createMockBuilder(ClassX.class).addMockedMethod("methodB").createMock();
expect(classx.methodA("hiyas")).andReturn("tomtom");
replay(classx);
String response = classx.methodA("hiyas");
assertEquals("tomtom",response);
}
}