What is the best way to verify a method was called on an object created within a method using Mockito?
I am new to Mockito and trying to verify that someMethod()
was called exactly once after invoking foo()
. Given the following class:
public class Foo {
public void foo() {
Bar bar = new Bar();
bar.someMethod();
}
}
How can I use Mockito to verify this method call? I would like to make the following verification:
verify(bar, times(1)).someMethod();
where bar
is a mocked instance of Bar
. What is the correct approach to achieve this?
Refactor the Code for Dependency Injection (Best Practice)
One way to handle this is to refactor the Foo class so that the Bar instance can be injected via the constructor or setter. This makes it much easier to mock and verify interactions with Bar.
Refactored Code:
public class Foo {
private Bar bar;
// Constructor for dependency injection
public Foo(Bar bar) {
this.bar = bar;
}
public void foo() {
bar.someMethod();
}
}
Test Code with Mockito:
import static org.mockito.Mockito.*;
public class FooTest {
@Test
public void testFoo() {
// Create mock
Bar mockBar = mock(Bar.class);
// Inject mock into Foo
Foo foo = new Foo(mockBar);
// Call the method to test
foo.foo();
// Verify if someMethod was called exactly once
verify(mockBar, times(1)).someMethod();
}
}
In this case, you’re directly injecting the mock Bar instance, which allows you to verify that someMethod() is called.
If refactoring is not an option and you need to test the method without modifying the code, you can use PowerMockito, which is an extension of Mockito that allows you to mock static methods, constructors, and other difficult-to-mock parts of code (like the instantiation of Bar inside foo()).
You can use PowerMockito to mock the creation of the Bar instance and then verify the method call.
Test Code Using PowerMockito:
import org.junit.Test;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import static org.mockito.Mockito.*;
public class FooTest {
@Test
public void testFoo() throws Exception {
// Mock the constructor of Bar
Bar mockBar = mock(Bar.class);
PowerMockito.whenNew(Bar.class).withNoArguments().thenReturn(mockBar);
// Create instance of Foo and call foo() method
Foo foo = new Foo();
foo.foo();
// Verify the method was called on the mocked Bar instance
verify(mockBar, times(1)).someMethod();
}
}
In this case, PowerMockito will intercept the call to new Bar() inside foo() and return the mocked Bar instance, allowing you to verify interactions with it.
Another solution is to spy on the Foo object itself, allowing you to verify the interactions with the Bar object through the spy. This is less common and more of a workaround if you don’t want to modify the original code.
Test Code with Mockito Spy:
import static org.mockito.Mockito.*;
public class FooTest {
@Test
public void testFoo() {
// Spy on the Foo class (this is not a mock, it's a partial mock)
Foo spyFoo = spy(new Foo());
// Mock the Bar instance within the Foo class
Bar mockBar = mock(Bar.class);
// Replace the Bar instance inside Foo with the mock
doReturn(mockBar).when(spyFoo).createBar();
// Call the method under test
spyFoo.foo();
// Verify the method was called on the mock Bar
verify(mockBar, times(1)).someMethod();
}
}
In this example, you spy on the Foo object and override the method that creates Bar. This approach is a bit more complex and usually requires you to provide an additional method like createBar() that can be mocked.