Norbert94
Norbert94

Reputation: 173

Mockito - mock subclass method call

I am working with legacy code and trying to write a unit test for an implementation I did. I have the following structure:

   AbstractClass:
    ----------------

    public AbstractClass {

    abstract method2();

     void method1(){   
      ...does something...
      ..calls --> method2()
     }
    }

    Subclass
    ------------
    public Subclass extends AbstractClass(){

     void method2(){
      ..do something....
      ..mockThisMethod()...

       return true;   
     }
 }

I have an abstract class which has some logic implemented in a specific method. This method calls than another method implemented in the subclass. The method in the subclass calls other methods which I want to mock.

Is this possible without changing the implementation code (hard to change)? Mos of the results are suggesting using mockito spying but it doesn't work.

I followed the TestDesign describer here:

https://www.tildedave.com/2011/03/06/pattern-stubbing-legacy-superclasses-with-mockito-spies.html

What I did is:

 Subclass subclass= spy(Subclass.class);
 when(subclass.mockThisMethod()).thenReturn(something);
 subclass.method1() (I am not sure if this line is correct?)

So what I want to avoid is, calling the method (mockThisMethod) in the Subclass. Since this method does some db-stuff an so on. I know it would be easier to test, if I use object composition instead of inheritance but at this point, it is hard to change the whole implementation. The code above is not working..I get a NPE.

Upvotes: 4

Views: 10076

Answers (1)

Maciej Kowalski
Maciej Kowalski

Reputation: 26502

1) You do not create a Spy by passing the class to the static Mockito.spy method. Instead, you must pass an instance of that particular class:

Subclass subclassSpy = spy(new Subclass());

Also, consider using annotations:

@Spy
private Subclass subclassSpy = new Sublcass();

@Before
public void init(){
   MockitoAnnotations.initMocks(this);
}

2) Avoid using when.thenReturn when stubbing a spy. Instead, use doReturn..when..methodCall:

doReturn(something).when(sublcass).mockThisMethod(); 

otherwise you will invoke the actual method while stubbing and this may lead to unwanted behavior and/or exceptions.

Upvotes: 5

Related Questions