Using PowerMockito.whenNew() is not getting mocked and original method is called

JavaJunitMockitoPowermock

Java Problem Overview


I have a code somewhat like this below:

Class A {
  public boolean myMethod(someargs) {
    MyQueryClass query = new MyQueryClass();
    Long id = query.getNextId();
    // some more code
  }
}
Class MyQueryClass     {
  ....
  public Long getNextId() {
    //lot of DB code, execute some DB query
    return id;
  }
}

Now I'am writing a test for A.myMethod(someargs). I want to skip the real method query.getNextId() and instead return a stub value. Basically, I want to mock MyQueryClass.

So in my test case, I have used:

MyQueryClass query = PowerMockito.mock(MyQueryClass.class);
PowerMockito.whenNew(MyQueryClass.class).withNoArguments().thenReturn(query);
when(query.getNextId()).thenReturn(1000000L);

boolean b = A.getInstance().myMethod(args);

//asserts

I used @RunWith(PowerMockRunner.class) and @PrepareForTest({MyQueryClass.class}) in the beginning of my test class.

But when I debug the test, it is still calling the real method getNextId() of the MyQueryClass class.

What am I missing here? Can anyone help as I am new to Mockito and PowerMockito.

Java Solutions


Solution 1 - Java

You need to put the class where the constructor is called into the @PrepareForTest annotation instead of the class which is being constructed - see Mock construction of new objects.

In your case:

@PrepareForTest(MyQueryClass.class)

@PrepareForTest(A.class)

More general:

@PrepareForTest(NewInstanceClass.class)

@PrepareForTest(ClassThatCreatesTheNewInstance.class)

Solution 2 - Java

As @TrueDub mentioned in his accepted reply, you need to add the class where the constructor is called to the @PrepareForTest.

However, if you do this, coverage for that class as reported by eclemma and Sonar will be zero for that class

Powermockito wiki

> We are going to replace Javassist with ByteBuddy (#727) and it should > help to resolve this old issue. But right now there is NO WAY TO USE > PowerMock with JaCoCo On-the-fly instrumentation. And no workaround to > get code coverage in IDE.

So the solution here would be to refactor the actual code to use a static factory that would return an instance of that class and then statically mock it.

Solution 3 - Java

Perhaps you can simply use

Mockito.doReturn(value).when(xxx)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser3942446View Question on Stackoverflow
Solution 1 - JavaTrueDubView Answer on Stackoverflow
Solution 2 - JavaACVView Answer on Stackoverflow
Solution 3 - JavajiajianchenView Answer on Stackoverflow