Spring Boot集成MyBatis做JUnit5测试时@Autowired无法注入Mapper
Spring Boot + MyBatis JUnit5测试Mapper无法注入问题解决方案
问题现象
使用Spring Boot和MyBatis编写JUnit5测试时,@Autowired无法注入Mapper,报NoSuchBeanDefinitionException异常。主应用正常启动运行所有功能无异常,仅测试场景下出现该问题。
报错信息
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'fehrm.servicelayer.mapper.EnqueueStatusDao' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1790) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1346) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300)
环境版本
- spring-boot: 2.6.1
- JUnit 5.8.1
- mybatis-starter 2.2.0
原有测试类代码
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestInstance; import org.mybatis.spring.boot.test.autoconfigure.MybatisTest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.jdbc.Sql; import org.springframework.context.annotation.Import; import fehrm.servicelayer.domain.EnqueueStatus; import fehrm.servicelayer.mapper.EnqueueStatusDao; @MybatisTest @ActiveProfiles("test") @Import(EnqueueStatusDao.class) public class EnqueueStatusDaoTest { @Autowired private EnqueueStatusDao enqueueStatusDao; @Test public void testSelect() { EnqueueStatus es = enqueueStatusDao.selectEnqueuePatient("1000000050"); Assertions.assertNotNull(es); } @Test public void testDelete() { enqueueStatusDao.delete("1000000050"); EnqueueStatus es = enqueueStatusDao.selectEnqueuePatient("1000000050"); Assertions.assertNull(es); } }
额外报错说明
移除测试包下标注@SpringBootApplication的启动类后,会触发如下报错:
Could not detect default configuration classes for test class [com.fehrm.servicelayer.mapper.EnqueueStatusDaoTest]: EnqueueStatusDaoTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
解决步骤
- 删除测试类上的
@Import(EnqueueStatusDao.class)注解:MyBatis的Mapper是接口,@Import无法直接注册接口类型的Bean,Mapper需要被MyBatis扫描后生成代理类,才能注册到Spring容器中。 - 调整测试目录下
@SpringBootApplication启动类的配置:- 保证启动类的包路径覆盖所有Mapper所在的包,比如Mapper在
fehrm.servicelayer.mapper下,启动类放在fehrm.servicelayer包下即可 - 直接在测试用启动类上添加
@MapperScan("fehrm.servicelayer.mapper")注解,显式指定Mapper的扫描路径,避免扫描范围不足的问题
- 保证启动类的包路径覆盖所有Mapper所在的包,比如Mapper在
- 核对
application-test配置文件的MyBatis配置,保证mybatis.mapper-locations配置和主应用配置一致,能正确扫描到Mapper对应的XML文件,同时配置正确的测试数据源信息。 - 可选方案:如果不想单独配置测试启动类,可以将测试类上的
@MybatisTest替换为@SpringBootTest(classes = 主项目启动类.class),直接使用主应用的启动类加载上下文,即可复用主应用的Mapper扫描配置。
内容的提问来源于stack exchange,提问作者Daniel Cosio
相关产品推荐
相关产品推荐

