Spring 框架整合 JUnit 单元测试——包含完整执行流程
7 Spring 框架整合 JUnit 单元测试
- 每次进行单元测试的时候,都需要编写创建工厂,加载配置文件等代码,比较繁琐。Spring 提供了整合 Junit 单元测试的技术,可以简化测试开发。
- 必须先有 Junit 单元测试的环境,也就是说已经导入 Junit 单元测试的 jar 包。6已经导入过了。使用的是 4.12 版本。(这个代码接着6的代码,在6的基础上继续写。)
- 再导入 spring-test 的坐标依赖
<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 容器进行管理
package com.qcby.entity;public class User {public void sayHello(){System.out.println("Hello....");} }
- 编写配置文件 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"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.编写测试代码
package 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 {// 测试哪一个对象,把该对象注入进来,在测试环境下,可以使用注解的方式注入测试的对象 // 按类型自动注入@Autowiredprivate User user;@Testpublic 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 等注解。如果上面代码要改成半注解的方式,需要这样写package 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 去扫描哪个包下面的注解。
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://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 纯注解方式
- 编写类和方法
package com.qcby.entity;import org.springframework.stereotype.Component;@Component public class Customer {public void save(){System.out.println("保存客户...");} }2.编写配置类
package 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.编写测试方法
package 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 {// 按类型注入@Autowiredprivate Customer customer;/*** 测试*/@Testpublic void run1(){customer.save();}}
- 编写类和方法,把该类交给 IOC 容器进行管理
