user1474111
user1474111

Reputation: 1516

Mockito is calling real method and thenReturn does not work

I have read some post about it but nothing solved my problem. I have a class which is singleton and one method of this class is being called inside another class. I need to mock this method call.

Class SingletonClass
{
     public static SingletonClass instance()
     {
           ......
           return instance;
     }

     public boolean methodToBeMocked(Object obj)
     {
          return false;
     }
}

And the another class is :

Class A
{
      Object doSomeStuff()
      {
            ......
            boolean result = SingletonClass.instance.methodToBeMocked();
      }
}

And I am mocking the method methodToBeMocked in my test class. I have tried to use doReturn instead of thenReturn as it is suggested in other posts but it did not help.

My test class is :

Class TestClass{

     Class A a = new A();

     public void test()
     {
          SingletonClass singletonClass = mock(SingletonClass.class);
          doReturn(true).when(singletonClass).methodToBeMocked(any());

          a.doSomeStuff(); // here mocked method returns false

          // but if I do this below it returns true !!!!
          Object obj = new Object();
          boolean result = singletonClass.mockedMethod(obj);
     }
}

So why I am not getting true when a.doSomeStuff is called ? What is wrong here ?

Upvotes: 3

Views: 6077

Answers (2)

John Czukkermann
John Czukkermann

Reputation: 615

For the benefit of others, I was using the following mock with the expectation it would not call someMock.someMethod(), unlike the when(someMock.someMethod()).doReturn("someString") usage.

Mockito.doReturn("someString").when(someMock).someMethod();

I could not understand why the real someMethod() was still being called. It turns out the method was specified as final. Mockito can't mock static or final methods.

Upvotes: 5

The problem is the static method public static SingletonClass instance(). The standard mockito library does not support mocking of static methods. I seen two solutions.

  1. You can rewrite small your code as:

Add new method getSingletonClassInstance() to be mocked in test

Class A {
       Object doSomeStuff()
       {
             ......
             boolean result = getSingletonClassInstance();
       }

       SingletonClass getSingletonClassInstance(){
             return SingletonClass.instance.methodToBeMocked();
       } 
}

use spy from mockito library to create an instance of Class A

import static org.mockito.Mockito.spy; .....

Class TestClass{

     public void test()
     {
          Class A a = spy(new A());
          SingletonClass singletonClass = mock(SingletonClass.class);
          doReturn(true).when(singletonClass).methodToBeMocked(any());

          doReturn(singletonClass).when(a).getSingletonClassInstance();

          a.doSomeStuff(); // here mocked method returns false

          // but if I do this below it returns true !!!!
          Object obj = new Object();
          boolean result = singletonClass.mockedMethod(obj);
     }
  }

More information about the spy in mockito. Spy used real instance and invoke real method but provide a functionality to mock specific method. Don't worry about the others method they will continue to work with real implementation, only mocked method will be affected.

  1. You can use power mockito to mock the public static SingletonClass instance()

Upvotes: 0

Related Questions