Junit5测试无法注入依赖但正常运行的应用程序可以注入它

Posted

技术标签:

【中文标题】Junit5测试无法注入依赖但正常运行的应用程序可以注入它【英文标题】:Junit5 Test not able to inject dependency but running application normally can inject it 【发布时间】:2021-07-01 21:57:42 【问题描述】:

目前,我正在一个项目中创建 @Entity Class , @Repository 用于存储一些信息。我像其他现有服务一样创建了一个服务,然后尝试将 @Service 带注释的类注入到带有 @RestController 注释的控制器中。它运行良好,能够正常运行应用程序而没有问题,即没有注入问题。

现在,当我尝试运行现有项目的测试时,它会失败,因为我的服务无法注入控制器类。收到此错误:

No qualifying bean of type 'com.example.service.exampleService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: 

现在我厌倦了字段和构造函数注入,每次都遇到相同的问题,但我遵循项目以前使用的相同模式。我很确定自动装配和其他工作都已正确完成,否则我创建的端点将无法正常工作。

我的问题是为什么会发生这种情况?即它在作为 Spring Boot 应用程序运行但不在测试上下文中运行时工作。我尝试关注其他帖子,但我无法关注它们,因为大多数帖子都是在 Junit4 之前的

目前我正在使用 Junit5。

这是我的测试类的样子

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;


@WebMvcTest
@AutoConfigureMockMvc(addFilters = false)
@ExtendWith(MockitoExtension.class)
public class sampleTest

 @Test
    public void sampletesting() throws Exception
      ...
    

这是我正在使用的依赖项和 Spring 启动版本:

    plugins 
        id 'org.springframework.boot' version '2.3.0.RELEASE'
        id 'io.spring.dependency-management' version '1.0.9.RELEASE'
        id 'java'
        id 'jacoco'
    
 testImplementation('org.springframework.boot:spring-boot-starter-test') 
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    
    testImplementation('org.mockito:mockito-core:3.5.13')
    testImplementation('org.mockito:mockito-inline:3.5.13')
    testImplementation('org.mockito:mockito-junit-jupiter:3.5.13')

我正在使用 Java 11

【问题讨论】:

我收到了同样的问题,我也需要这方面的帮助。 因为您使用的是@WebMvcTest,它只会引导应用程序的Web 部分,不包括服务、daos 等。如果您的控制器使用服务,您需要添加@MockBean为该测试服务。 为什么不使用@SpringBootTest注解?根据我的经验,如果您不使用 @SpringBootTest 注释,则必须手动配置上下文和 bean @M.Deinum 太棒了!它起作用了,我实际上并没有意识到它。感谢您的帮助! @AbhishekSengupta 如果您也遇到此问题,请尝试 M. Deinum 所说的话。 【参考方案1】:

@WebMvcTest 用于您只想加载应用程序中所有可用 bean 的特定部分的情况:web 控制器(以及其他一些与 web-mvc 相关的类,如转换器等)。它不会加载任何服务,这是有意完成的:

使用@WebMvcTest 意味着您要测试控制器代码(所有注释都已正确定义等)。通常在这种测试中,您会调用控制器方法,使用名为 mockMvc 的东西并检查预期结果

您可以阅读here for example 了解此类测试。通常控制器会注入服务,在这种情况下你应该在服务上使用@MockBean

所以严格来说这就是失败的原因。

现在,如果您想加载整个应用程序上下文,请考虑使用@SpringBootTest。您还必须考虑在测试期间应该可以访问的数据库。

【讨论】:

以上是关于Junit5测试无法注入依赖但正常运行的应用程序可以注入它的主要内容,如果未能解决你的问题,请参考以下文章

[JUnit] JUnit5 基础 3 - 依赖注入,假设(assume),开启/禁用测试 与 嵌套测试

带有硒测试容器的junit5无法正常工作

使用 spring boot gradle 插件无法使用依赖管理执行 junit5 测试

在Maven项目中运行JUnit 5测试用例

如何使用 SpringBoot2、JUnit5 和 Kotlin 将配置属性注入单元测试

由于注入持久性依赖项失败,无法在 Spring Boot 应用程序上运行测试