I´m trying to make a unit test in springboot but the test throw me java.lang.IllegalStateException: Failed to load ApplicationContext

Viewed 473

When i try to create a class test always throw me the next error

java.lang.IllegalStateException: Failed to load ApplicationContext

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userServiceImplement': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.project.sophosproject.repository.UserRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

I've spent hours trying to solve the problem but I can't find a real solution, maybe you could help me to find a solution.

UserServiceImplement CLASS

@Service
@Transactional
@RequiredArgsConstructor
public class UserServiceImplement implements UserService{

private final UserRepository userRepository;

@Override
public GenericResponse listAllUser() {

    var apiResponse = new GenericResponse();

    try{
        List<User> userList = userRepository.findAll();
        if(userList == null){
            apiResponse.setOperationSuccess(true);
            apiResponse.setMessage("No Records");
            return apiResponse;
        }

        long totalRecords = userList.stream().count();

        apiResponse.setOperationSuccess(true);
        apiResponse.setObjectResponse(userList);
        apiResponse.setTotalRecords(totalRecords);
    }catch (Exception ex){
        apiResponse.setOperationSuccess(false);
        apiResponse.setMessage(ex.getMessage().toString());
    }

    return apiResponse;
}

@Override
public User getUser(Long id) {
    return userRepository.findById(id).orElse(null);
}

@Override
public User createUser(User user) {
    return userRepository.save(user);
}

@Override
public User updateUser(User user) {
    User userDb = getUser(user.getIdUser());
    if(null == userDb){
        return null;
    }
    userDb.setNameUser(user.getNameUser());
    userDb.setLastNameUser(user.getLastNameUser());
    userDb.setUserCode(user.getUserCode());
    userDb.setEmailUser(user.getEmailUser());
    userDb.setUserAddress(user.getUserAddress());
    userDb.setPosition(user.getPosition());
    userDb.setTaskList(user.getTaskList());

    return userRepository.save(userDb);
}

@Override
public User deleteUser(Long id) {
    User userDb = getUser(id);
    if(null == userDb){
        return null;
    }

    userDb.setStateUser(false);
    return userRepository.save(userDb);
}

@Override
public List<User> findByTask(Task task) {
    return userRepository.findByTask(task);
}
}

UserServiceImplementTest CLASS

@SpringBootTest(classes = UserServiceImplement.class)
class UserServiceImplementTest {

@Mock
private UserRepository userRepository;
private UserService userService;

@BeforeEach
public void setUp(){
    MockitoAnnotations.openMocks(this);
    userService = new UserServiceImplement(userRepository);

    User userTest = User.builder().idUser(1L)
                        .nameUser("Michael").lastNameUser("Torres")
                        .userCode("MTO").emailUser("michaeltorresos92@gmail.com")
                        .userAddress("KR103").position("Developer").stateUser(true)
                        .taskList((List<Task>) Task.builder().idTask(1).build()).build();

    Mockito.when(userRepository.findById(1L))
            .thenReturn(Optional.of(userTest));

}

@Test
public void whenValidGetId_ThenReturnUser(){
    User found = userService.getUser(1L);

    Assertions.assertThat(found.getNameUser()).isEqualTo("Michael");
}

}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.0</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.project.sophos</groupId>
<artifactId>SophosProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SophosProject</name>
<description>Demo project for Sophos</description>
<properties>
    <java.version>17</java.version>
    <spring-cloud.version>2021.0.3-SNAPSHOT</spring-cloud.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--<dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-sleuth</artifactId>
    </dependency>-->

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <!--<dependency>
        <groupId>com.microsoft.sqlserver</groupId>
        <artifactId>mssql-jdbc</artifactId>
        <scope>runtime</scope>
    </dependency>-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mariadb.jdbc</groupId>
        <artifactId>mariadb-java-client</artifactId>
        <version>2.7.3</version>
    </dependency>

</dependencies>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <excludes>
                    <exclude>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok</artifactId>
                    </exclude>
                </excludes>
            </configuration>
        </plugin>
    </plugins>
</build>
<repositories>
    <repository>
        <id>spring-snapshots</id>
        <name>Spring Snapshots</name>
        <url>https://repo.spring.io/snapshot</url>
        <releases>
            <enabled>false</enabled>
        </releases>
    </repository>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/milestone</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

UserRepository interface

@Repository
public interface UserRepository extends JpaRepository<User, Long> {

public List<User> findByTask(Task task);
}

SophosProjectApplication class

@SpringBootApplication
@ComponentScan(basePackages = {"com.project.sophosproject"})
public class SophosProjectApplication {

public static void main(String[] args) {
    SpringApplication.run(SophosProjectApplication.class, args);
}

}

UserRepository Interface

public interface UserService {
public GenericResponse listAllUser();
public GenericResponse getUser(Integer id);
public User createUser(User user);
public User updateUser (User user);
public User deleteUser(Integer id);
}
1 Answers

Spring cannot find a UserRepository bean, because the way the test is currently configured causes it to be excluded.

Take a look at the Javadoc for classes on the @SpringBootTest annotation:

The component classes to use for loading an ApplicationContext. Can also be specified using @ContextConfiguration(classes=...). If no explicit classes are defined the test will look for nested @Configuration classes, before falling back to a @SpringBootConfiguration search.

That means that if you provide classes, then Spring will attempt to configure only those bean classes. In this case, your class under test, UserServiceImplement, depends on a UserRepository- but your @SpringBootTest(classes = UserServiceImplement.class) annotation dictates that only UserServiceImplement will be instantiated, and therefore the dependency cannot be satisfied.

If you remove classes=... and instead just use @SpringBootTest, your @SpringBootApplication annotated class will be loaded, and the whole application context will be created (including the missing repository) as opposed to just the one class specified.


An aside, as your test class is currently written, there's not much of a benefit to instantiating an application context or marking the test class as @SpringBootTest. Doing that is typically reserved for integration tests, where multiple components need to be loaded so that their integrations can be tested (hence the name).

Instead, you've mocked the only dependency, UserService, and are manually instantiating UserServiceImplement. That means you've not used Spring at all in your test. Your test is testing one unit, UserServiceImplement, and therefore doesn't benefit from the integration environment provided by @SpringBootTest.

Related