-1

I have a scenario like this

MyInterface myObject = new MyInterfaceImplementedClass();
myObject.get(...)

I want to mock the MyInterfaceImplementedClass, I tried like below

private MyInterface mockMyObject
private MyInterfaceImplementedClass mockMyClassObject

// the below compilation error 
whenNew(MyInterfaceImplementedClass.class).withNoArguments().thenReturn(mockMyObject);
// no compilation error but not giving mocking instance at runtime
whenNew(MyInterfaceImplementedClass.class).withNoArguments().thenReturn(mockMyClassObject);

Please help me on this

luk2302
  • 55,258
  • 23
  • 97
  • 137
  • What does "*but not giving mocking instance at runtime"* mean? – luk2302 May 01 '18 at 16:58
  • 1
    In using PowerMockito, it is critically important that we see your `@RunWith` and `@PrepareForTest` annotations on the test class. Please edit your question to include them. (PowerMock manipulates the Java classloader, so those annotations are often the difference between a failure and a success.) If you aren't using those annotations, please tell us that, too: it might be a very quick solution to your problem! – Jeff Bowman May 01 '18 at 17:14
  • Hi Jeff, Yes, you are right, after adding my test class in side @PrepareForTest, it works as expected, thanks a lot for your help – user3346145 May 03 '18 at 16:42

1 Answers1

2

Solved in the comments:

after adding my test class in side @PrepareForTest, it works as expected

In short, Mockito writes a generated subclass for the class you're trying to mock, which allows it to intercept the behavior of overridable methods (i.e. non-final instance methods). This handles all interfaces and most abstract and concrete classes. However, if you're trying to mock the behavior of final or static methods, including constructors, there's nothing Mockito can do1: the consuming class contains a reference to the exact real implementation without a lookup to the virtual method table. The only way out is to rewrite and replace the bytecode of an existing class, which is exactly what PowerMock does.

It can often just overwrite the class you're trying to mock, but in certain circumstances you need to list the class under test or the test class itself.

Consequently, almost all tests that exercise PowerMock's features require a @PrepareForTest, as well as a @RunWith statement that ensures that the test class uses PowerMock's classloader to enable that rewriting.


1 since Mockito 2.1, Mockito can use instrumented classloaders to do some of the things that were previously only available in PowerMock.

Jeff Bowman
  • 90,959
  • 16
  • 217
  • 251
  • Great Explanation Jeff, Thank you – user3346145 May 04 '18 at 07:09
  • @user3346145 You're welcome! If you're satisfied with this answer, you can [accept the answer](https://meta.stackexchange.com/q/5234/201031) by clicking the checkmark above and next to the answer box. It's a nice way to tell folks that this question has been answered, and gives you a little rep bonus for following through. Good luck with your work! – Jeff Bowman May 04 '18 at 15:44