Reputation: 381
I have the following Java classes:
public class A
{
@Autowired
private B b;
public int aFn()
{
int something = b.bFn();
}
}
public class B
{
@Autowired
private C c;
public int bFn()
{
int something = c.cFn();
}
}
public class C
{
public int cFn()
{
return 231;
}
}
And the following test using Mockito to test the above code:
public class test
{
@Autowired
private A a;
private C c;
@Test
public void testA()
{
c = mock(C.class);
when(c.cFn(),anyInt()).thenReturn(something);
assertEquals(0, a.aFn());
}
}
When I debug testA, I find that real c.Cfn() gets executed, not the mocked one. Is there anything what I am doing incorrectly here? Please help!
Upvotes: 6
Views: 14950
Reputation: 1019
Forget whether what you want to mock is direct or nested. Think of it from Spring's philosophical point of view.
What you are essentially want to do is mock a bean.
In your case, you have to mock bean for Class c using @MockBean annotations.
@RunWith(SpringRunner.class)
public class Test {
...
@MockBean private C c;
...
}
Please refer this article for details.
Upvotes: 0
Reputation: 691685
First of all, you should always mock the direct dependencies of an object, and not its transitive dependencies. So you should mock B, and not C, to test A. Then you would write a unit test for B by mocking C.
Second: you're not injecting the mock anywhere in the unit test. What you should have is:
public class Test {
// not autowired here
private A a;
private B mockB;
@Test
public void testA() {
mockB = mock(B.class);
when(b.bFn(), anyInt()).thenReturn(something);
// the missing part: injecting the mock into the tested object
a = new A(mockB);
// or a = new A();
// a.setB(mockB);
assertEquals(0, a.aFn());
}
}
When you use mock(B.class), you get one mock instance of B. That doesn't mean that all the other instances of B will do what the mock does.
Mocking C to test A is a bad practice: unit tests should test one class in isolation of the others. But if you really want that, then create a mock C, create a B and inject the mock C inside it, then create an A and inject the B inside it.
A --> B --> mockC
Upvotes: 11