Spring 框架整合 JUnit 单元测试
在日常开发中,我们经常需要测试 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/beanshttp://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 {@Autowiredprivate User user; // 按类型自动注入@Testpublic 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 {@Autowiredprivate Customer customer;@Testpublic 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 文件。
