In this tutorial, we will discuss how to verify method calls on objects created within methods using Mockito. This is a common scenario in unit testing where we need to ensure that certain methods are called when expected.
Introduction to Mockito
Mockito is a popular open-source framework for creating mock objects in Java. It allows us to isolate dependencies and test the behavior of our code without actually calling external methods. In this tutorial, we will use Mockito to verify method calls on objects created within methods.
Problem Statement
Suppose we have a class Foo
with a method foo()
that creates an object of type Bar
and calls its someMethod()
. We want to test whether someMethod()
is called exactly once when foo()
is invoked.
public class Foo {
public void foo() {
Bar bar = new Bar();
bar.someMethod();
}
}
Solution Using Dependency Injection
One way to solve this problem is by using dependency injection. We can inject an instance of Bar
into the Foo
class and then use Mockito to verify whether someMethod()
was called.
public class Foo {
private Bar bar;
public Foo(Bar bar) {
this.bar = bar;
}
public void foo() {
bar.someMethod();
}
}
In our test class, we can create a mock instance of Bar
and inject it into the Foo
class.
@Test
public void testDoFoo() {
Bar bar = Mockito.mock(Bar.class);
Foo foo = new Foo(bar);
foo.foo();
Mockito.verify(bar, Mockito.times(1)).someMethod();
}
Solution Using @InjectMocks
Another way to solve this problem is by using the @InjectMocks
annotation provided by Mockito. This annotation allows us to inject mock objects into our class under test.
public class Foo {
private Bar bar = new Bar();
public void foo() {
bar.someMethod();
}
}
In our test class, we can use the @InjectMocks
annotation to inject a mock instance of Bar
into the Foo
class.
@RunWith(MockitoJUnitRunner.class)
public class FooTest {
@Mock
private Bar bar;
@InjectMocks
private Foo foo;
@Test
public void testDoFoo() {
Mockito.doNothing().when(bar).someMethod();
foo.foo();
Mockito.verify(bar, Mockito.times(1)).someMethod();
}
}
Solution Using PowerMockito
We can also use PowerMockito to verify method calls on objects created within methods. This approach requires us to use the @PrepareForTest
annotation and the PowerMockRunner
class.
@RunWith(PowerMockRunner.class)
@PrepareForTest({ Foo.class })
public class FooTest {
@Mock
private Bar bar;
@Test
public void testDoFoo() throws Exception {
PowerMockito.whenNew(Bar.class).withNoArguments().thenReturn(bar);
Foo foo = new Foo();
foo.foo();
Mockito.verify(bar, Mockito.times(1)).someMethod();
}
}
Conclusion
In this tutorial, we discussed how to verify method calls on objects created within methods using Mockito. We explored three different solutions: dependency injection, @InjectMocks
, and PowerMockito. Each solution has its own advantages and disadvantages, and the choice of which one to use depends on our specific testing needs.
Best Practices
When writing unit tests, it’s essential to follow best practices such as:
- Keep our tests simple and focused on a single piece of functionality.
- Use mocking frameworks like Mockito to isolate dependencies and make our tests more efficient.
- Use annotations like
@InjectMocks
to simplify the process of injecting mock objects into our class under test. - Use PowerMockito when we need to verify method calls on objects created within methods.
By following these best practices, we can write high-quality unit tests that ensure our code is reliable and maintainable.