How to mock a protected third party code method

Using Mockito I want to mock a property of a class so that I can check the output

public class MyClass extends ThirdPartyFramework {
  Output goesHere;

  @Override
  protected setup(){
    goesHere = new Output();
  }

  //...      
}

public abstract class ThirdPartyFramework {
  protected setup(){...}
  //...
}

      

I need to inject the layout of the Output class so that I can verify that my code has written the correct output.

  • But I can't just @InjectMock

    because the setup()

    mid-runtime method is called and overwrites my injection.

  • And I can't just make the setting public in MyClass

    , because the test code I'm running is shared and should work for all subclasses ThirdPartyFramework

    , so I only have a reference to ThirdPartyFramework

    what it means setup()

    .

+3


source to share


3 answers


I decided to solve this by wrapping ThirdPartyFramework

and placing this class in the same package as the class ThirdPartyFramework

.



This way I could mock protected methods with Mockito. I was then able to use @InjectMock

to inject the layout of an object Output

and manage its method calls through that layout.

+1


source


Are you tuned in to Mockito? I ask from the Mockito Frequently Asked Questions The Mockito FAQ states that it does not support mocking static methods, which I think you will need in this case to create your mock instead of the actual output.

I used PowerMock for a similar scenario:

whenNew(NewInstanceClass.class).withArguments(any()).thenReturn(mockObject);

      

which says that every time a NewInstanceClass is created, my mockObject is returned regardless of what constructor arguments were used and who created the NewInstanceClass at what time.



I also found the following example in the PowerMock docs:

PowerMock.expectNew(NewInstanceClass.class).andReturn(mockObject)

      

In fact, you can use it even if you are tied to Mockito, PowerMock contains helpers for Mockito to solve exactly this problem, which will allow you to use Mockito for all tests and PowerMock to mock constructs. Like this:

whenNew(Output.class).withNoArguments().thenReturn(yourOutputMock);

      

+1


source


How about adding a setter for "goHere" and then set setup () and change goHere if its value is null. This way you can inject a value into testing that will not be overridden. Something like:

protected void setGoesHere( Output output ){
    goesHere = output;
} 

@Override
protected void setup(){
    if(goesHere != null) goesHere = new Output();
}

      

Hope it helps.

0


source







All Articles