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!
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With