Reputation: 33
I am doing JUnit tests with Mockito on Spring Mvc. The tests are using @InjectMock and @Mock with when(method(..)).thenReturn(X). The issue is how to @Mock methods that are within a @Inject instance?
I have tried creating two instances such as @InjectMocks Foo fooInstance and @Mock Foo fooInstanceMock; My way of thinking is to differentiate from what instance to inject and what to mock. I also tried using Spy with InjectMocks but it returns a exception.
Actual Class Syntax-
class Foo {
public X(..) {
...
Y(...); // method call to Y
...
}
public Y(..) {
...
}
}
Test Syntax -
public class FooTest {
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
@InjectMocks
Foo fooInstance;
@Mock
Foo fooInstanceMock;
@Test
public void xTest{
when(fooInstanceMock.Y(..)).thenReturn(true);
Boolean result = fooInstance.X(25);
Assert.assertTrue(result == true)
}
}
I except the output to be true as when then return true but since it thinks it is a injectMock and it goes into the implementation.
Upvotes: 2
Views: 7156
Reputation: 311228
@InjectMocks
is used to inject mocks you've defined in your test in to a non-mock instance with this annotation.
In your usecase, it looks like you're trying to do something a bit different - you want a real intance of Foo
with a real implementation of x
, but to mock away the implmentation of y
, which x
calls. This can be done by partial mocking, or in Mockito's terminology, spying:
public class FooTest{
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
// Default constructor is used to create a real Foo instance.
// In the test's body, though, we'll override the behavior of SOME of the methods
@Spy
Foo fooInstance;
@Test
public void xTest {
doReturn(true).when(fooInstance).y(/* arguments, presumably 25 */);
Boolean result = fooInstance.x(25);
Assert.assertTrue(result);
}
}
Upvotes: 5