I've got a problem with mockito tests named "Cannot instantiate @InjectMocks field named 'userService' of type 'UserServiceImpl'. You haven't provided the instance at field declaration so I tried to construct the instance." I've been searching through stackoverflow but unfortunately I haven't found right solution for myself. So, I've got interface 'UserService', its implementation and several methods which I wanna tests.
UserService:
public interface UserService {
Optional<User> getByToken(String token);
PagingDto<User> getUsers(String filter, Integer startIndex, Integer count);}
UserServiceImpl:
public class UserServiceImpl extends AbstractPagingService<User, Integer, UserEntity> implements UserService {
private final UserRepository userRepository;
@Autowired
public UserServiceImpl(ProviderConfiguration providerConfiguration, UserRepository userRepository) {
super(providerConfiguration.getFilter().getMaxResult(), userRepository, Sort.by("surname"));
this.userRepository = userRepository;
}
four methods
Test class:
@ExtendWith(SpringExtension.class)
class UserServiceImplTest {
private static final String TOKEN = "token";
@InjectMocks
private UserServiceImpl userService;
@Spy
private UserRepository userRepository;
@Test
void testGetByToken() {
final UserEntity userEntity = new UserEntity();
final int id = 1;
final User expectedUser = new User();
final String email = "[email protected]";
final String surname = "surname";
final String name = "name";
final String patronymic = "patronymic";
userEntity.setId(id);
expectedUser.setId(id);
expectedUser.setEmail(email);
expectedUser.setSurname(surname);
expectedUser.setName(name);
expectedUser.setPatronymic(patronymic);
when(userRepository.findById(id)).thenReturn(Optional.of(userEntity));
final User actualUser = userService.getByToken(TOKEN).orElseThrow();
assertEquals(expectedUser, actualUser);
assertEquals(email, userEntity.getEmail());
assertEquals(surname, userEntity.getSurname());
assertEquals(name, userEntity.getName());
assertEquals(patronymic, userEntity.getPatronymic());
}
@Test
void testGetAbsentUserByToken() {
assertFalse(userService.getByToken(TOKEN).isPresent());
}
@Test
void testEmptyUser() {
when(userRepository.findById(any())).thenThrow(IllegalArgumentException.class);
assertFalse(userService.getByToken(TOKEN).isPresent());
}
Everything is OK if I didn't extends AbstractPagingService<User, Integer, UserEntity>. But if I do there always be a mistake I mentioned above.
CodePudding user response:
You are missing a mock for ProviderConfiguration
which is a required dependency for your service.
@ExtendWith(SpringExtension.class)
class UserServiceImplTest {
private static final String TOKEN = "token";
@InjectMocks
private UserServiceImpl userService;
@Spy
private UserRepository userRepository;
@Mock
private ProviderConfiguration providerConfiguration;
Probably needs some more steps to be properly set up, including mocking getFilter()
or by having the mock return mocks (generally discouraged).
If ProviderConfiguration
is a data class without much logic, consider assigning a real config in your test:
@ExtendWith(SpringExtension.class)
class UserServiceImplTest {
private static final String TOKEN = "token";
private ProviderConfiguration providerConfiguration = createTestProviderConfiguration();
@InjectMocks
private UserServiceImpl userService;
@Spy
private UserRepository userRepository;
private static ProviderConfiguration createTestProviderConfiguration() {
final Filter filter = new Filter();
filter.setMaxResult(42);
final ProviderConfiguration cfg = new ProviderConfiguration();
cfg.setFilter = filter;
return cfg;
}