Reputation: 4785
This is the test class:
@MockBean
private UserRepository userRepository;
@Before
public void beforeClass() {
String mobile;
when(this.userRepository.findByMobile(Mockito.anyString())).thenAnswer(new Answer<User>() {
@Override
public User answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
return MockData.getUserByMobile((String) args[0]);
}
});
}
@Test
@WithUserDetails(value = MockData.CUSTOMER_USERNAME, userDetailsServiceBeanName = "customizedUserDetailsService")
public void testAdd() throws Exception {}
And this is the userDetails
implementation:
@Autowired
private UserRepository userRepository;
@Override
@Transactional
public UserDetails loadUserByUsername(String username) {
User user = (User) userRepository.findByMobile(username); // user is always null
What I expect is when userRepository.findByMobile
is called, it should call the getUserByMobile
method defined in @Before
. But obviously the Mockito
config does not work OR userRepository
fail to mock. What's wrong and how to solve it?
Upvotes: 0
Views: 140
Reputation: 4785
UserRepository is used in userDetails implementation, and it needs to be injected into userDetails as described in this. However because XXRepository is in interface, so @InjectedMock cannot be used. Then classes become: Test class:
@MockBean
private UserService userService;
@InjectMocks
private CustomizedUserDetailsService customizedUserDetailsService;
@Before
public void before() {
MockitoAnnotations.initMocks(this);
when(this.userService.findByMobile(Mockito.anyString())).thenAnswer(new Answer<User>() {
@Override
public User answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
return MockData.getUserByMobile((String) args[0]);
}
});
}
@Test
@WithUserDetails(value = MockData.CUSTOMER_USERNAME, userDetailsServiceBeanName = "customizedUserDetailsService") {}
And userDetails:
@Autowired
private UserService userService;
@Override
@Transactional
public UserDetails loadUserByUsername(String username) {
User user = (User) userService.findByMobile(username);
I can see that the userService in userDetails is the same userService mocked in test class, however @Before
method is called after the @WithUserDetails userDetails
. So finally in order to achieve loading MockData user been, I think I have to create another userDetails just for UT. EDIT 2: Actually, I have tried it without @InjectMocks and using userService (originally I was using userRepository), it works too.
Upvotes: 2