4

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?

2
  • This seems an odd thing to want to test. You should test that bar has the right effect; not which secondary methods it uses to achieve that effect. Your unit tests shouldn't depend on a particular implementation of a method - this isn't the right way to test. Commented Mar 9, 2018 at 12:40
  • @DawoodibnKareem: I realize this isn't the preferred way of unit testing, but because there are many conditionals I wanted to test the main method independently from the child methods. And test the child methods seperately. I guess I may have to go back to the drawing board Commented Mar 9, 2018 at 13:53

2 Answers 2

7

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.

Sign up to request clarification or add additional context in comments.

Comments

4

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"); } } 

2 Comments

This doesn't seem to work with a non 0-arg constructor. I get a MockitoException: Caused by: org.mockito.internal.creation.instance.InstantationException: Unable to create instance of 'Foo$$EnhancerByMockitoWithCGLIB$$fdafa2c2'. Please ensure it has 0-arg constructor which invokes cleanly. I'll update my question to better reflect the problem
@Lao Of course, Mockito.spy() can receive a class to instantiate, or an already instantiated object

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.