7 Spring 框架整合 JUnit 单元测试
-
每次进行单元测试的时候,都需要编写创建工厂,加载配置文件等代码,比较繁琐。Spring 提供了整合 Junit 单元测试的技术,可以简化测试开发。
-
必须先有 Junit 单元测试的环境,也就是说已经导入 Junit 单元测试的 jar 包。6已经导入过了。使用的是 4.12 版本。(这个代码接着6的代码,在6的基础上继续写。)
-
再导入 spring-test 的坐标依赖
java<dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.0.2.RELEASE</version> <scope>test</scope> </dependency>7.1 XML 配置 + Spring Test 注解驱动测试
-
编写类和方法,把该类交给 IOC 容器进行管理
javapackage com.qcby.entity; public class User { public void sayHello(){ System.out.println("Hello...."); } } -
编写配置文件 applicationContext_test.xml
java<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--整合单元测试--> <bean id="user" class="com.qcby.entity.User"/> </beans>3.编写测试代码
javapackage com.qcby; import com.qcby.entity.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 单元测试 * */ @RunWith(value = SpringJUnit4ClassRunner.class) // 运行单元测试 @ContextConfiguration(value = "classpath:applicationContext.xml") // 加载类路径下的配置文件 public class Demo5 { // 测试哪一个对象,把该对象注入进来,在测试环境下,可以使用注解的方式注入测试的对象 // 按类型自动注入 @Autowired private User user; @Test public void run1(){ // 创建工厂,加载配置文件...... // 调用对象的方法 user.sayHello(); } }代码执行流程:
- @RunWith(SpringJUnit4ClassRunner.class): 这个注解告诉 JUnit:"不要用你默认的方式来运行测试,而是交给 SpringJUnit4ClassRunner 来处理。" 这个 Runner 会为你创建 Spring 的测试环境。
- @ContextConfiguration("classpath:applicationContext_test.xml"): 这个注解告诉 Spring Test Runner:"请加载 applicationContext_test.xml 这个配置文件来初始化 Spring 容器(ApplicationContext)。"
- 容器初始化: Spring Test Runner 会读取你的 XML 文件,看到里面有 这行配置。于是,它会根据这个配置,创建一个 User 类的实例,并把它存入 Spring 容器中,Bean 的名字就是 user。
- @Autowired private User user;: 在测试类 Demo5 被创建后,Spring Test 会在这个测试类上也应用依赖注入。它看到 user 这个字段,就会去已经初始化好的 Spring 容器里查找一个类型为 User 的 Bean,然后把它注入进来。
- 问题
- 为什么我上面测试代码的xml文件里没有加 也能跑起来呢
- 这是因为你使用了 Spring Test 框架 (@RunWith(SpringJUnit4ClassRunner.class))。
- Spring Test 框架为了方便测试,它会自动为你配置一个默认的、功能齐全的测试环境。这个环境默认就已经开启了注解驱动的注入功能。所以,即使你的 XML 文件里没有 ,@Autowired 在测试环境中也能生效。
- 但是,在一个标准的、非测试的 Spring 应用(比如一个 Web 应用)中,如果你的 XML 配置文件里没有 或 ,那么 @Autowired 和 @Value 注解将完全无效。
- 我上面那种方式是半注解的方式吗
不是,"半注解" 方式,通常指的是 注解注册 Bean + XML 配置其他内容" 的混合模式。在这种模式下,我们不再在 XML 中用 标签来声明普通的业务类,而是使用 @Component, @Service 等注解。
如果上面代码要改成半注解的方式,需要这样写
javapackage com.qcby.entity; import org.springframework.stereotype.Component; @Component // 告诉 Spring,这是一个需要被管理的组件 public class User { public void sayHello(){ System.out.println("Hello from a component...."); } }修改 applicationContext_test.xml 文件,需要告诉 Spring 去扫描哪个包下面的注解。
java<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 开启注解扫描 --> <!-- Spring 会去 com.qcbyjy 包及其子包下查找所有带有 @Component, @Service 等注解的类,并为它们创建 Bean --> <context:component-scan base-package="com.qcby" /> </beans>测试代码 Demo5.java 无需任何改动。
测试流程变为:- Spring 加载 XML,看到 。
- Spring 扫描到 User 类上的 @Component 注解,自动为它创建一个 Bean(默认名字是 user)。
- @Autowired 从容器中取出 User Bean 注入到测试类中。
- Spring 的三种主要配置方式:
注册 Bean 的方式决定了你的配置风格是纯 XML、半注解还是纯注解。
|--------------|------------------------------|-----------------------------|------------------------------------------------|---------------------------------------------|
| 配置方式 | 如何注册 Bean | 如何注入依赖 | 优点 | 缺点 |
| 纯 XML | | 或 | 对所有开发者都直观,与代码解耦,适合管理第三方库的 Bean。 | 配置繁琐,维护困难,当项目庞大时 XML 文件会变得非常臃肿。 |
| 半注解 (混合) | 业务类用 @Component 等注解,通过 扫描注册。 | @Autowired , @Resource 等注解。 | 结合了 XML 和注解的优点,灵活。业务代码清晰,第三方库配置在 XML 中。 | 配置分散在代码和 XML 中,不够统一。 |
| 纯注解 (推荐) | 业务类用 @Component 等注解。 | @Autowired , @Resource 等注解。 | (现代 Spring 开发首选) 配置与代码在一起,清晰、简洁、类型安全,易于重构。 | 需要额外的配置类( @Configuration )来代替 XML 中的一些复杂配置。 |7.2 纯注解方式
-
编写类和方法
javapackage com.qcby.entity; import org.springframework.stereotype.Component; @Component public class Customer { public void save(){ System.out.println("保存客户..."); } }2.编写配置类
javapackage com.qcby.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; /** * Spring 整合 Junit 配置类*/ // 声明 @Configuration // 扫描包结构 @ComponentScan(value = "com.qcby.entity") public class SpringConfig6 { }3.编写测试方法
javapackage com.qcby; import com.qcby.config.SpringConfig6; import com.qcby.entity.Customer; 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(); } }
-