Reputation: 115
I have Class A and Class B. B is autowired in class A. Now I want to test the flow using mockito.
So the problem is when I tried to mock the class A and B in my test case using @InjectMock
its going to class A but its not invoking class B.
I dont want to mock the class B which is autowired in class A, from A its should make call to class B and get the user details data.
@Component
public class A {
@Autowired
private B b;
public Users getUsers() {
Long id = 10;
b.getUserDetails(id);
// some Logic
}
}
@Component
public class B {
public UserDetails getUserDetails(Long id) {
// some logic to get users details ..
}
}
@RunWith(MockitoJUnitRunner.class)
public class TestA {
@InjectMocks
private A a;
@InjectMocks
private B b;
@Test
public void testA() {
Users actual = a.getUsers();
assertEquals(actual, expected());
assertNotNull(actual);
}
private Users expected() {
return new Users(); // expected users object
}
}
Upvotes: 1
Views: 56
Reputation: 11
You should change @InjectMocks annotation on above B to @Spy and you should add @Spy on above A also. Because you want to use B.class's and A.class's real methods. Why you need to use @Spy ?
If you use @Mock, by default for all methods, mock returns null, an empty collection or appropriate primitive / primitive wrapper value (e.g. 0, false, null, ...)
If you use @Spy then the real methods are called (unless a method was stubbed).
As a result, your creation in TestA.class should be like :
@Spy @InjectMocks private A a;
@Spy private B b;
Upvotes: 0
Reputation: 58774
You should use @Spy on B
in order to use real B
class
@Spy
private B b;
the spy will wrap an existing instance. It will still behave in the same way as the normal instance – the only difference is that it will also be instrumented to track all the interactions with it.
Upvotes: 2