Reputation: 55
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?
Upvotes: 4
Views: 11570
Reputation: 690
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");
}
}
Upvotes: 4
Reputation: 27018
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.
Upvotes: 7