简体   繁体   中英

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

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.

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)

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.

It also doesn't work with method reference. For example PowerMockito can't mock new instance for TargetClass here:

TargetClass target = Optional.ofNullable( x )
                                     .map( TargetClass::new )
                                     .orElse( null );

也许你可以简单地使用

Mockito.doReturn(value).when(xxx)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM