Issue
I don't know why this is happening, the Autowired of the service works in the controller but not works in the Junit test class
Here is my JUnit Test:
package com.crmbackend.user;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Test;
import com.crmbackend.entity.Role;
import com.crmbackend.entity.User;
import com.crmbackend.userService.UserService;
@DataJpaTest(showSql = true)
@AutoConfigureTestDatabase(replace = Replace.NONE)
@Rollback(false)
public class UserServiceTests {
@Autowired
private TestEntityManager entityManager;
@Autowired
private UserService service;
@Test
public void testCreateNewUserWithSingleRolePasswordEncode() {
Role roleUser = entityManager.find(Role.class, 3);
User userLucas = new User("lucas9324", "Lucas", "Tom", "qqq542417349", "[email protected]", "7364832234");
userLucas.addRole(roleUser);
User savedUser = service.save(userLucas);
assertThat(savedUser.getId()).isGreaterThan(0);
}
}
Here is my service class:
package com.crmbackend.userService;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import com.crmbackend.entity.User;
@Service
@Transactional
public class UserService {
@Autowired
private UserRepository userRepo;
@Autowired
private RoleRepository roleRepo;
@Autowired
private PasswordEncoder passwordEncoder;
public User getByUsername(String username) {
return userRepo.getUserByUsername(username);
}
private void encodePassword(User user) {
String encodedPassword = passwordEncoder.encode(user.getPassword());
user.setPassword(encodedPassword);
}
public User save(User user) {
boolean isUpdatingUser = (user.getId() != null);
if (isUpdatingUser) {
User existingUser = userRepo.findById(user.getId()).get();
if (user.getPassword().isEmpty()) {
user.setPassword(existingUser.getPassword());
} else {
encodePassword(user);
}
} else {
encodePassword(user);
}
return userRepo.save(user);
}
}
The @Autowired of
@Autowired
private UserService service;
Works fine in the controller but not working in the JUnit test.... Always got not qualifying bean found issue.
Any suggestions?
Solution
DataJpaTest
is a slice test, it does not load the entire Spring Application Context i.e. it will not load your service but only whats required to test JPA functionality.
If you want to load your UserService
as a bean you will need to import.
However given all the dependencies that are also autowired in your UserService
you're likely better just using SpringBootTest
to load the entire context.
You can exclude autoconfigurations/configurations, filter component scans if you are using component scanning over configurations if loading the entire context is taking too long.
For information on DataJpaTest
You can use the @DataJpaTest annotation to test JPA applications. By default, it scans for @Entity classes and configures Spring Data JPA repositories. If an embedded database is available on the classpath, it configures one as well. SQL queries are logged by default by setting the spring.jpa.show-sql property to true. This can be disabled using the showSql() attribute of the annotation.
Regular @Component and @ConfigurationProperties beans are not scanned when the @DataJpaTest annotation is used. @EnableConfigurationProperties can be used to include @ConfigurationProperties beans.
Answered By - Darren Forsythe