Spring Boot 测试:bean 未注入

Posted

技术标签:

【中文标题】Spring Boot 测试:bean 未注入【英文标题】:Spring Boot Test: bean not injected 【发布时间】:2022-01-19 11:10:27 【问题描述】:

这里是我的测试地点:

src/test/java
└── cat
    └── gencat
        └── catsalut
            └── hes
                └── mpi
                    └── unit
                        └── mapper
                            └── PatientMapperTest.java

PatientMapperTest.java 是:

@SpringBootTest
@RequiredArgsConstructor
public class Patient 
    
    private final TypesMapper typesMapper;

    @Test
    void test() 
        assertNull(this.typesMapper);
    


我也试过这段代码(删除lombok注释并显式初始化typesMapper字段):

@SpringBootTest
public class PatientMapperTest 
    
    private final TypesMapper typesMapper;

    public PatientMapperTest(TypesMapper typesMapper) 
        this.typesMapper = new TypesMapperImpl();
    

    @Test
    void test() 
        assertNull(this.typesMapper);
    


我的行为和以前完全一样。

然而,当我执行mvn test 时,它似乎被忽略了:

$ mvn test
[INFO] 
[INFO] Results:
[INFO] 
[ERROR] Errors: 
[ERROR]   PatientMapperTest.test » ParameterResolution No ParameterResolver registered f...
[INFO] 
[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0

相关pom依赖:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.5</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

有什么想法吗?

【问题讨论】:

这个错误并不意味着你的bean没有被注入它是别的东西。请看***.com/questions/51867650/… @Autowired注释构造函数参数是否有效? 【参考方案1】:

与您的生产代码不同,您不必使用 @Autowired 注释您的公共构造函数,当您想要使用 JUnit 5 为您的测试注入构造函数时,您需要它。

JUnit Jupiter SpringExtension(使用@SpringBootTest 自动注册)确保解析带有@Autowired 注释的任何参数。如果你不添加@Autowired,JUnit 不知道如何解决这个参数,因为没有人觉得有责任,因为 Spring 扩展只有在使用 @Autowired(或其他标识符)时才会启动:

@SpringBootTest
public class PatientMapperTest 
    
    private final TypesMapper typesMapper;

    @Autowired
    public PatientMapperTest(TypesMapper typesMapper) 
        this.typesMapper = typesMapper;

        // the original assignment doesn't make sense, why inject the instance and then manually call the constructor?
        // this.typesMapper = new TypesMapperImpl();
    

    @Test
    void test() 
        assertNull(this.typesMapper);
    


作为替代方案,您也可以使用@TestConstructor 注解:

@SpringBootTest
@TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL)
public class PatientMapperTest 
    
    private final TypesMapper typesMapper;

    public PatientMapperTest(TypesMapper typesMapper) 
      this.typesMapper = typesMapper;
    

如果您想深入了解并了解 SpringExtension 何时解析来自 TestContext 的参数,请查看 SpringExtension#supportsParameter

您还可以安全地使用字段注入进行测试:

@SpringBootTest
public class PatientMapperTest 
     
    @Autowired
    private TypesMapper typesMapper;


    @Test
    void test() 
        assertNull(this.typesMapper);
    


【讨论】:

以上是关于Spring Boot 测试:bean 未注入的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能将此 Spring Boot 服务类注入 JUnit 测试类?预计至少有 1 个 bean 有资格作为 autowire 候选者

spring boot 测试无法注入 TestRestTemplate 和 MockMvc

Spring boot 将配置文件属性注入到一个bean中

在 Spring Boot MVC 测试中自定义 bean

测试单元 Spring boot:无法注册模拟 bean

Spring Boot - 测试 - 拆除 bean