Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mockito - Verifying if a method calls another method within the same class

I am trying to test whether a method calls another method within the same class. Example:

public class Foo {

    public void bar(String a){
        switch(a) {
            case "callBaz":
                baz(a);
                break;
            case "callBat":
                bat(a);
                break;
            default:
                System.out.println("Input was " + a);
        }
    } 

    public void baz(String b){
        System.out.println(b);
    }

    public void bat(String c){
        System.out.println(c);
    }
}

However if I try mockito verify on the class itself:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
public class FooTest {
    @Test
    public void testBazCalledFromBar(){
        Foo foo = new Foo();
        foo.bar("callBaz");
        Mockito.verify(foo).baz("callBaz");
    }
}

I get the exception:

org.mockito.exceptions.misusing.NotAMockException: 
Argument passed to verify() is of type Foo and is not a mock!
Make sure you place the parenthesis correctly!
See the examples of correct verifications:
    verify(mock).someMethod();
    verify(mock, times(10)).someMethod();
    verify(mock, atLeastOnce()).someMethod();

When using the mock: ...

@RunWith(SpringJUnit4ClassRunner.class)
public class FooTest {
    @Test
    public void testBazCalledFromBar(){
        Foo fooMock = Mockito.mock(Foo.class);
        fooMock.bar("callBaz");

        Mockito.verify(fooMock).baz("callBaz");
    }
}

I get the exception:

Wanted but not invoked:
foo.baz("callBaz");
-> at com.mn.stagportal.view.employee.FooTest.testBazCalledFromBar(FooTest.java:15)
However, there were other interactions with this mock:
foo.bar("callBaz");
-> at com.mn.stagportal.view.employee.FooTest.testBazCalledFromBar(FooTest.java:13)

Does anyone know how to test if baz("callBaz") is called?

like image 798
Lao Avatar asked Sep 10 '25 00:09

Lao


2 Answers

This should work.

@RunWith(SpringJUnit4ClassRunner.class)
public class FooTest {
  @Test
  public void testBazCalledFromBar(){
    Foo fooMock = Mockito.mock(Foo.class);
    doCallRealMethod().when(fooMock).bar(anyString());
    fooMock.bar("callBaz");

    Mockito.verify(fooMock).baz("callBaz");
  }
}

The issue is, since fooMock is a mock, when it encounters this line

fooMock.bar("callBaz");

It doesn't know what to do. You need to tell Mockito, whether you want to mock the method call or you want to call the real method.

Verify can only work if the code flow goes to this real method and called the baz method.

like image 110
pvpkiran Avatar answered Sep 12 '25 14:09

pvpkiran


You shouldn't mock the tested object, you can spy instead:

@RunWith(SpringJUnit4ClassRunner.class)
public class FooTest {
  @Test
  public void testBazCalledFromBar(){
    Foo foo = Mockito.spy(Foo.class);
    foo.bar("callBaz");
    Mockito.verify(foo).baz("callBaz");
  }
}

or

@RunWith(SpringJUnit4ClassRunner.class)
public class FooTest {
  @Test
  public void testBazCalledFromBar(){
    Foo foo = Mockito.spy(new Foo(/* params */));
    foo.bar("callBaz");
    Mockito.verify(foo).baz("callBaz");
  }
}
like image 29
Klaimmore Avatar answered Sep 12 '25 13:09

Klaimmore