Mockito spy returns a different result than calling the actual method

I have the following code:

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

I am writing unit test for this method. When I run the VTDGen mock VTDGen , the parseFile method returns true . However, when I trick him into a spy, he 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 got the impression that Mockito spy objects should not change the behavior of wrapped objects, so why am I getting false instead of true?

+4
source share
3 answers

Perhaps this is because you are returning vtdGenMock not vtgGenSpy to

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

+1
source

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

 VTDGen vtgGenSpy = PowerMockito.spy(vtdGen); 

Also make sure your combinations of Mockito / Powermock versions are compatible. I am using Mockito 1.8.5 and Powermock 1.4.10.

The following tests pass for me (TestNG):

 @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 the device under test:

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

This was in orien's answer, albeit indirectly: did you include @PrepareForTest (ClassCallingNewVTDGen.class)?

This is a class call.

 new VTDGen() 

which should be prepared for testing. The answer from orien is Uo.class

A source

+1
source

Source: https://habr.com/ru/post/1380390/


All Articles