Home > Software engineering >  Cannot instantiate @InjectMocks field named 'userService' of type 'UserServiceImpl�
Cannot instantiate @InjectMocks field named 'userService' of type 'UserServiceImpl�

Time:10-20

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;
  }
  • Related