相关配置
- 导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<scope>test</scope>
</dependency>
- 测试类加上注解
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
@RunWith(SpringRunner.class)
class SpringbootProjectApplicationTests {
@Autowired
ApplicationContext applicationContext;
@Test
void contextLoads() {
Arrays.stream(applicationContext.getBeanDefinitionNames()).forEach(System.out::println);
}
}
ApplicationContextTests 类上的 @SpringBootTest 和 @RunWith 注解构成了一套完整的测试方案。
@SpringBootTest注解
SpringBoot 程序的入口是 Bootstrap 类,直接使用 @SpringBootTest 注解提供的默认功能就是对作为 Bootstrap 类的 Application 类进行测试。更常见的做法是在 @SpringBootTest 注解中用classes属性指定该 Bootstrap 类,并设置测试的 Web 环境。
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, classes={MyUserService.class})
@RunWith(SpringRunner.class)
@SpringBootTest - webEnvironment
WebEnvironment
MOCK
:加载 WebApplicationContext 并提供一个 Mock 的 Servlet 环境,此时内置的 Servlet 容器并没有正式启动。
在多数场景下,一个真实的 Servlet 环境对于测试而言过于重量级,通过 MOCK 环境则可以缓解这种环境约束所带来的困扰。
RANDOM_PORT
:加载 EmbeddedWebApplicationContext 并提供一个真实的 Servlet 环境,然后使用一个随机端口启动内置容器。这个用的比较多
DEFINED_PORT
:这个配置也是通过加载 EmbeddedWebApplicationContext 提供一个真实的 Servlet 环境,但使用的是默认端口,如果没有配置端口就使用 8080。
NONE
:**加载 ApplicationContext 但并不提供任何真实的 Servlet 环境。**测试类启动时就只会初始化 Spring 上下文,不再启动 Tomcat 容器了。
如果你要测试的方法不需要用到 Tomcat 容器, 则可以使用NONE
模式。比如:
- 测试 DAO 类的CRUD
- 测试Service 类的业务方法
- 测试工具类的公用方法
- 测试配置文件类是否读取到了正确的值
如果注解@SpringBootTest(classes = 启动类名称.class)中配置了项目启动类,则该测试类可以放在test.java下任何包中。
如果注解@SpringBootTest没有配置里面的参数classes = Application.class,则需要确保test.java下的测试类包与启动类所在的包一致,即在test.java下也需要创建com.xunan.demo包,并将测试类放在该包下。
classes
classes 属性用来指定运行测试类需要装载的 class 集合,如果不指定,那么会默认装载 @SpringBootConfiguration 注解标注的类。
如果不指定classes属性,那么启动测试类时需要加载的Bean的数量和正常启动一次入口类加载的 Bean 数量是一样的。
如果你的项目中有很多个 Bean, 特别是有以下几种时:
- 有 CommandLineRunner 的实现类
- 用 @PostConstruct 注解指定了初始化方法的类
这几种类在程序初始化的过程中都会运行自身的业务代码或者初始化代码,从而延后了测试方法的运行。
在这种情况下,我们在编写测试类的时候,如果明确这个测试类会用到哪几个 Bean,则可以在 classes 属性处指定,之后启动测试类的时候,就只会加载需要的 Bean 到上下文中,从而加快启动速度。
@RunWith 注解
在上面的示例中,我们还看到一个由 JUnit 框架提供的 @RunWith 注解,它用于设置测试运行器。例如,我们可以通过 @RunWith(SpringJUnit4ClassRunner.class) 让测试运行于 Spring 测试环境。
虽然这我们指定的是 SpringRunner.class,实际上,SpringRunner 就是 SpringJUnit4ClassRunner 的简化,它允许 JUnit 和 Spring TestContext 整合运行,而 Spring TestContext 则提供了用于测试 Spring 应用程序的各项通用的支持功能。
数据层测试回滚
测试用例如果测试时产生了事务提交就会在测试过程中对数据库数据产生影响,进而产生垃圾数据。这个过程不是我们希望发生的,作为开发者测试用例该运行运行,但是过程中产生的数据不要在我的系统中留痕,这样该如何处理呢?
我们只需要在原始测试用例中添加注解@Transactional即可实现当前测试用例的事务不提交。当程序运行后,只要注解@Transactional出现的位置存在注解@SpringBootTest,springboot就会认为这是一个测试程序,无需提交事务,所以也就可以避免事务的提交。
@SpringBootTest
@Transactional
@Rollback(false)
public class SqlTest {
@Autowired
private UserMapper userMapper;
@Test
void test01() {
User user = new User();
user.setName("cabbage");
user.setAge(20);
user.setEmail("cabbage@qq.com");
userMapper.insert(user);
}
}
总结:
- 在springboot的测试类中通过添加注解@Transactional来阻止测试用例提交事务
- 通过注解@Rollback控制springboot测试类执行结果是否提交事务,需要配合注解@Transactional使用
Spock使用:
https://blog.youkuaiyun.com/wx17343624830/article/details/126060104
https://it.cha138.com/javascript/show-95243.html