在日常开发中,我们经常需要测试 Spring 管理的 Bean。
如果手动创建 Spring 容器、加载配置文件来获取 Bean,会显得非常繁琐。
为此,Spring 提供了 Spring Test 模块,可以与 JUnit 整合,大大简化测试代码。
1. 整合的作用
在没有整合之前,每次单元测试都要写类似代码:
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) context.getBean("user");
user.sayHello();
整合 JUnit 后,就可以直接通过注入获取 Bean,无需手动加载 Spring 容器。
2. 环境准备
要让 Spring 支持 JUnit 单元测试,需要两个依赖:
<!-- JUnit 依赖(4.12版本) -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- Spring Test 依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.2.RELEASE</version>
<scope>test</scope>
</dependency>
💡 注意:
Spring Test 模块必须与 Spring 框架的版本匹配,否则可能出现加载失败或注入异常。
3. XML 配置方式整合 JUnit
3.1 创建待测试类
package com.qcbyjy.demo5;
public class User {
public void sayHello(){
System.out.println("Hello...");
}
}
3.2 编写 Spring 配置文件
applicationContext_test.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 将 User 对象交由 IOC 容器管理 -->
<bean id="user" class="com.qcbyjy.demo5.User"/>
</beans>
3.3 编写测试类
package com.qcbyjy.test;
import com.qcbyjy.demo5.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* Spring 整合 JUnit 单元测试(基于 XML 配置)
*/
@RunWith(SpringJUnit4ClassRunner.class) // 使用 Spring 提供的 JUnit 运行器
@ContextConfiguration("classpath:applicationContext_test.xml") // 指定配置文件位置
public class Demo5 {
@Autowired
private User user; // 按类型自动注入
@Test
public void run1(){
user.sayHello(); // 测试方法
}
}
3.4 执行流程说明
-
JUnit 启动测试。
-
SpringJUnit4ClassRunner会自动创建 Spring 容器。 -
@ContextConfiguration告诉 Spring 去哪里加载配置。 -
@Autowired把容器中的 Bean 自动注入进来。 -
执行
@Test测试方法。
4. 注解方式整合 JUnit(无 XML 配置)
Spring 5.x 推荐使用 纯注解方式配置,更简洁、可维护性更高。
4.1 创建待测试类
package com.qcbyjy.demo6;
import org.springframework.stereotype.Component;
@Component
public class Customer {
public void save(){
System.out.println("保存客户...");
}
}
4.2 创建 Spring 配置类
package com.qcbyjy.demo6;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* Spring 整合 JUnit 的注解配置类
*/
@Configuration // 声明为配置类(相当于applicationContext.xml)
@ComponentScan("com.qcbyjy.demo6") // 扫描包,加载Bean
public class SpringConfig6 {
}
4.3 编写测试类
package com.qcbyjy.test;
import com.qcbyjy.demo6.Customer;
import com.qcbyjy.demo6.SpringConfig6;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* Spring 整合 JUnit(注解方式)
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig6.class) // 指定配置类
public class Demo6 {
@Autowired
private Customer customer;
@Test
public void run1(){
customer.save();
}
}
5. 两种整合方式对比
| 特点 | XML 配置方式 | 注解配置方式 |
|---|---|---|
| 配置文件 | 需要 applicationContext.xml |
无需 XML,仅用 Java 配置类 |
| 扫描 Bean | <bean> 标签 |
@ComponentScan 注解 |
| 适用场景 | 旧项目、混合配置 | 新项目、全注解配置 |
| 灵活性 | 略低 | 更强,推荐使用 |
6. 常见问题与解决
| 问题 | 原因 | 解决方法 |
|---|---|---|
NullPointerException 注入失败 |
没有加载正确的配置文件或包路径错误 | 检查 @ContextConfiguration 路径 |
NoSuchBeanDefinitionException |
Bean 未注册到容器中 | 检查 @ComponentScan 范围或 XML 配置 |
| Spring 容器无法启动 | Spring Test 版本不兼容 | 确保 spring-test 与 Spring 主包版本一致 |
| 使用 JUnit5 无效 | Spring4~5 默认仅支持 JUnit4 | 换用 SpringExtension 与 JUnit5 配合 |
✅ 7. 总结要点
-
整合 Spring 与 JUnit 可以自动加载 Spring 容器,简化测试代码。
-
使用
@RunWith(SpringJUnit4ClassRunner.class)指定运行器。 -
使用
@ContextConfiguration指定配置文件或配置类。 -
使用
@Autowired直接注入需要测试的 Bean。 -
推荐使用 纯注解方式 配置,避免 XML 文件。