Mockito spy returns different result than actual method call

1.6k Views Asked by At

I have the following code:

public Object parse(){
      ....
      VTDGen vg = new VTDGen();
      boolean parsed = vg.parseFile(myFile.getAbsolutePath(), false);
}

I am writing a unit test for this method. When I run the method without mocking VTDGen the parseFile method returns true. However, when I mock it with a spy, it returns false.

My test is as follows:

@Before
public void setup(){
     VTDGen vtgGen = new VTDGen();
     VTDGen vtgGenSpy = PowerMockito.spy(vtdGen);
     PowerMockito.whenNew(VTDGen.class).withNoArguments().thenReturn(vtdGenSpy);

}


@Test
public void myTest(){
    // when I run the test parseFile returns false
    // if I remove the mocking in the setup, parseFile returns true
}

I was under the impression that Mockito's spy objects should not change the behavior of wrapped objects, so why am I getting false instead of true?

3

There are 3 best solutions below

0
On

Maybe it is because you are returning vtdGenMock not vtgGenSpy in

PowerMockito.whenNew(VTDGen.class).withNoArguments().thenReturn(vtdGenMock);

2
On

When spying on Powermocked classes you should use the PowerMockito.spy(...) method:

VTDGen vtgGenSpy = PowerMockito.spy(vtdGen);

Also ensure your version combinations of Mockito/Powermock are compatible. I'm using Mockito 1.8.5 and Powermock 1.4.10.

The following tests (TestNG) pass for me:

@PrepareForTest({VTDGen.class, Uo.class})
public class UoTest extends PowerMockTestCase {

    private VTDGen vtdGen;
    private VTDGen vtdGenSpy;
    private Uo unitUnderTest;

    @BeforeMethod
    public void setup() {
        vtdGen = new VTDGen();
        vtdGenSpy = PowerMockito.spy(vtdGen);
        unitUnderTest = new Uo();
    }

    @Test
    public void testWithSpy() throws Exception {
        PowerMockito.whenNew(VTDGen.class).withNoArguments().thenReturn(vtdGenSpy);

        boolean result = unitUnderTest.parse();

        assertTrue(result);
    }

    @Test
    public void testWithoutSpy() throws Exception {
        PowerMockito.whenNew(VTDGen.class).withNoArguments().thenReturn(vtdGen);

        boolean result = unitUnderTest.parse();

        assertTrue(result);
    }
}

For unit under test:

public class Uo {
    public boolean parse() {
        VTDGen vg = new VTDGen();
        return vg.parseFile("test.xml", false);
    }
}
1
On

This was in orien's reply although sort of indirectly: Did you include @PrepareForTest(ClassCallingNewVTDGen.class)?

It's the class calling

new VTDGen()

that has to be prepared for test. In orien's answer, it is Uo.class

Source