目录
1、简介
2、Junit存在的问题
3、回顾Junit注解
4、集成步骤
4.1、导入坐标
4.2、@Runwith
4.3、@ContextConfiguration
4.4、@Autowired
4.5、@Test
4.6、代码
5、补充说明
5.1、@Runwith
5.2、BlockJUnit4ClassRunner
5.3、没有配置@Runwith
⭐作者介绍:大二本科网络工程专业在读,持续学习Java,努力输出优质文章
⭐作者主页:@逐梦苍穹
⭐所属专栏:JavaEE、Spring
1、简介
在 Spring 中集成 JUnit 是一种常见的测试方式,可以使用 JUnit 运行 Spring 容器中的测试用例。这样你可以测试 Spring 容器中的 Bean,进行集成测试,确保你的 Spring 配置和组件能够正确地工作。
2、Junit存在的问题
原始Junit测试Spring的问题:在原来的测试代码中,都要反复编写加载配置文件或者配置类的代码,重复性比较高。两行代码的作用是获取容器,如果不写的话,直接会提示空指针异常。所以又不能轻易删掉。
解决思路:
①让SpringJunit负责创建Spring容器,但是需要将配置文件的名称告诉它
②将需要进行测试Bean直接在测试类中进行注入
3、回顾Junit注解
注解 | 描述 |
@Test | 标记方法为测试方法。 |
@Before | 标记方法在每个测试方法执行前执行。 |
@After | 标记方法在每个测试方法执行后执行。 |
@BeforeClass | 标记静态方法,在所有测试方法执行前执行。 |
@AfterClass | 标记静态方法,在所有测试方法执行后执行。 |
@Ignore | 标记测试方法忽略,不会执行。 |
@RunWith | 指定运行测试用例的运行器(Runner) |
@Rule | 创建测试规则,可以自定义测试方法的行为。 |
@Parameterized | 创建参数化测试,对每组参数执行测试。 |
@RunWith(Parameterized.class) | 运行参数化测试。 |
@Test(expected = Exception.class) | 指定测试方法期望抛出的异常。 |
@Test(timeout = 1000) | 指定测试方法的最大执行时间。 |
4、集成步骤
Spring集成Junit步骤:
① 导入spring集成Junit的坐标
② 使用@Runwith
注解替换原来的运行期
③ 使用@ContextConfiguration
指定配置文件或配置类
④ 使用@Autowired
注入需要测试的对象
⑤ 创建测试方法进行测试
4.1、导入坐标
此处需要注意的是,spring5 及以上版本要求 junit 的版本必须是 4.12 及以上
4.2、@Runwith
@RunWith注解是指定运行测试用例的运行器(Runner)
使用@Runwith注解替换原来的运行器:@RunWith(SpringJUnit4ClassRunner.class)
4.3、@ContextConfiguration
使用@ContextConfiguration
指定配置文件或配置类
@ContextConfiguration
是 Spring Test 模块中的注解,用于在测试类上指定 Spring 配置文件的位置,从而在测试过程中启动 Spring 容器并进行依赖注入。
在 Spring 的单元测试和集成测试中,我们通常需要配置一个或多个 Spring 配置文件,以便在测试中使用 Spring 的功能。@ContextConfiguration
注解提供了一种简便的方式来指定这些配置文件的位置。
@ContextConfiguration
注解的常用属性:
- locations:用于指定 Spring 配置文件的位置,可以是一个或多个配置文件路径,多个路径使用数组形式。例如:
@ContextConfiguration(locations = "classpath:applicationContext.xml")
或@ContextConfiguration(locations = {"classpath:applicationContext.xml", "classpath:spring-beans.xml"})
。 - classes:用于指定 Spring 配置类的类型,可以是一个或多个 Java 配置类。例如:
@ContextConfiguration(classes = MyConfig.class)
或@ContextConfiguration(classes = {MyConfig1.class, MyConfig2.class})
。 - initializers:用于指定 Spring ApplicationContextInitializer 类型的类,可以在 Spring 容器启动前执行自定义初始化操作。
- inheritLocations:是否继承父类的配置文件位置,默认为 true。如果设置为 false,则不继承父类的配置。
- inheritInitializers:是否继承父类的初始化器,默认为 true。如果设置为 false,则不继承父类的初始化器。
4.4、@Autowired
使用@Autowired
注入需要测试的对象
4.5、@Test
4.6、代码
package com.xzl.test;
import com.xzl.config.SpringConfiguration;
import com.xzl.dao.UserDao;
import com.xzl.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.sql.DataSource;
import java.sql.SQLException;
/**
* @author 逐梦苍穹
* @date 2023/7/21 23:15
*/
@RunWith(SpringJUnit4ClassRunner.class)
//加载spring核心配置文件
//@ContextConfiguration(value = {"classpath:applicationContext.xml"})
//加载spring核心配置类
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {
@Autowired
public UserDao userDao;
@Autowired
public UserService userService;
@Autowired
@Qualifier(value = "dataSource_druid")
public DataSource dataSourceDruid;
@Autowired
@Qualifier(value = "dataSource_c3p0")
public DataSource dataSourceC3p0;
@Test
public void test1() throws SQLException {
System.out.println(dataSourceDruid.getConnection());
System.out.println(dataSourceC3p0.getConnection());
}
@Test
public void test2(){
userDao.save();
userService.save();
}
}
5、补充说明
5.1、@Runwith
@RunWith(SpringJUnit4ClassRunner.class) 是 JUnit 中的一个注解,用于指定运行测试用例时使用的运行器(Runner)。在 Spring 集成测试中,我们通常需要启动 Spring 容器,并将测试类中的 Bean 注入到容器中,以便进行真实的集成测试。
使用 @RunWith(SpringJUnit4ClassRunner.class) 注解,我们可以告诉 JUnit 使用 SpringJUnit4ClassRunner 运行器来运行测试类。这个运行器会启动 Spring 容器,并在测试类中注入 Spring 容器中的 Bean。这样,我们就可以在测试方法中调用这些 Bean,进行真实的集成测试。
5.2、BlockJUnit4ClassRunner
BlockJUnit4ClassRunner 是 JUnit 4 框架中的默认测试运行器(Runner)。它是 JUnit 4 的标准运行器,用于执行测试用例并提供了一些测试框架的核心功能。
当我们没有在测试类上使用 @RunWith 注解来指定特定的运行器时,
JUnit 4 就会默认使用BlockJUnit4ClassRunner 来运行测试。
BlockJUnit4ClassRunner 提供了以下主要功能:
- 创建测试实例:它负责实例化测试类,并在执行测试方法时创建测试实例。
- 执行测试方法:它负责执行标记了 @Test 注解的测试方法,并提供一些测试方法执行的钩子(hook)方法,如 @Before 和 @After。
- 支持测试规则:JUnit 4 引入了测试规则(@Rule 注解)的概念,用于扩展测试用例的行为。BlockJUnit4ClassRunner 支持 @Rule 注解,并在测试执行期间调用测试规则。
- 支持超时测试:可以通过 @Test(timeout) 注解设置测试方法的最大执行时间,如果测试方法在指定时间内没有完成,测试将失败。
- 支持测试异常:可以使用 @Test(expected) 注解来指定测试方法期望抛出的异常,如果测试方法没有抛出指定的异常,则测试失败。
- 支持参数化测试:虽然 BlockJUnit4ClassRunner 不支持参数化测试,但我们可以使用 @RunWith(Parameterized.class) 来启用参数化测试,它是 JUnit 4 内置的另一个运行器。
总的来说,BlockJUnit4ClassRunner 提供了 JUnit 4 测试框架的基本功能,它是默认的运行器,可以满足大多数简单的单元测试需求。对于更复杂的测试需求,我们可以选择其他适合的运行器,如 SpringJUnit4ClassRunner 用于 Spring 集成测试,或者使用 Parameterized 运行器进行参数化测试。
5.3、没有配置@Runwith
JUnit 将会使用默认的运行器 BlockJUnit4ClassRunner 来运行测试用例。这个运行器不会启动 Spring 容器,也不会处理任何 Spring 相关的注解。
在没有配置 @RunWith(SpringJUnit4ClassRunner.class) 的情况下,测试用例将按照普通的 JUnit 测试方式执行。这意味着测试方法将独立运行,不会进行 Spring 的集成测试。
例如,假设有以下的测试类:
import org.junit.Test;
public class MyTest {
@Test
public void test1() {
System.out.println("Test 1 is executed.");
}
@Test
public void test2() {
System.out.println("Test 2 is executed.");
}
}
如果没有配置 @RunWith(SpringJUnit4ClassRunner.class),则测试方法 test1() 和 test2() 将按照普通的 JUnit 测试方式运行。在运行测试时,控制台将输出:
因为没有配置 @RunWith(SpringJUnit4ClassRunner.class),所以 Spring 相关的注解如 @Autowired、@ContextConfiguration 等都不会生效。测试用例也不会与 Spring 容器进行集成,无法注入 Spring 容器中的 Bean。
因此,如果需要进行 Spring 集成测试并使用 Spring 相关的注解,就需要在测试类上配置 @RunWith(SpringJUnit4ClassRunner.class),以启动 Spring 容器并进行集成测试。