Exception : mockito wanted but not invoked, Actually there were zero interactions with this mock

JavaUnit TestingMockito

Java Problem Overview


I have interface

Interface MyInterface {
  myMethodToBeVerified (String, String);
}

And implementation of interface is

class MyClassToBeTested implements MyInterface {
   myMethodToBeVerified(String, String) {
    …….
   }
}

I have another class

class MyClass {
    MyInterface myObj = new MyClassToBeTested();
    public void abc(){
         myObj.myMethodToBeVerified (new String(“a”), new String(“b”));
    }
}

I am trying to write JUnit for MyClass. I have done

class MyClassTest {
    MyClass myClass = new MyClass();
  
    @Mock
    MyInterface myInterface;

    testAbc(){
         myClass.abc();
         verify(myInterface).myMethodToBeVerified(new String(“a”), new String(“b”));
    }
}

But I am getting mockito wanted but not invoked, Actually there were zero interactions with this mock at verify call.

can anyone suggest some solutions.

Java Solutions


Solution 1 - Java

You need to inject mock inside the class you're testing. At the moment you're interacting with the real object, not with the mock one. You can fix the code in a following way:

void testAbc(){
     myClass.myObj = myInteface;
     myClass.abc();
     verify(myInterface).myMethodToBeVerified(new String("a"), new String("b"));
}

although it would be a wiser choice to extract all initialization code into @Before

@Before
void setUp(){
     myClass = new myClass();
     myClass.myObj = myInteface;
}

@Test
void testAbc(){
     myClass.abc();
     verify(myInterface).myMethodToBeVerified(new String("a"), new String("b"));
}

Solution 2 - Java

Your class MyClass creates a new MyClassToBeTested, instead of using your mock. My article on the Mockito wiki describes two ways of dealing with this.

Solution 3 - Java

@Jk1's answer is fine, but Mockito also allows for more succinct injection using annotations:

@InjectMocks MyClass myClass; //@InjectMocks automatically instantiates too
@Mock MyInterface myInterface

But regardless of which method you use, the annotations are not being processed (not even your @Mock) unless you somehow call the static MockitoAnnotation.initMocks() or annotate the class with @RunWith(MockitoJUnitRunner.class).

Solution 4 - Java

@jk1 answer is perfect, since @igor Ganapolsky asked, why can't we use Mockito.mock here? i post this answer.

For that we have provide one setter method for myobj and set the myobj value with mocked object.

class MyClass {
    MyInterface myObj;

    public void abc() {
        myObj.myMethodToBeVerified (new String("a"), new String("b"));
    }

    public void setMyObj(MyInterface obj)
    {
        this.myObj=obj;
    }
}

In our Test class, we have to write below code

class MyClassTest {

MyClass myClass = new MyClass();
        
    @Mock
    MyInterface myInterface;
        
    @test
    testAbc() {
        myclass.setMyObj(myInterface); //it is good to have in @before method
        myClass.abc();
        verify(myInterface).myMethodToBeVerified(new String("a"), new String("b"));
     }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser3096719View Question on Stackoverflow
Solution 1 - JavaJk1View Answer on Stackoverflow
Solution 2 - JavaDawood ibn KareemView Answer on Stackoverflow
Solution 3 - JavaKevin WelkerView Answer on Stackoverflow
Solution 4 - Javavijaya kumarView Answer on Stackoverflow