Spring Boot学习笔记(五)—— 使用JUnit5编写单元测试

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/swift0824/article/details/83928694

1.开发环境

  • Mac OS 10.14
  • JDK8
  • Maven 3.5.3
  • Eclipse 4.9.0
  • Spring Boot 2.0.5.RELEASE
  • JUnit 5.1.1

2.JUnit5简介[1]

JUnit 5跟以前的JUnit版本不一样,它由几大不同的模块组成,这些模块分别来自三个不同的子项目。
JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage
主要注解:

  • @BeforeAll 类似于JUnit 4的@BeforeAll,表示使用了该注解的方法应该在当前类中所有使用了@Test@RepeatedTest@ParameterizedTest或者@TestFactory注解的方法之前执行,必须为static
  • @BeforeEach 类似于JUnit 4的@Before,表示使用了该注解的方法应该在当前类中每一个使用了@Test@RepeatedTest@ParameterizedTest或者@TestFactory注解的方法之前执行
  • @Test 表示该方法是一个测试方法
  • @DisplayName 为测试类或测试方法声明一个自定义的显示名称
  • @AfterEach 类似于JUnit 4的@After,表示使用了该注解的方法应该在当前类中每一个使用了@Test@RepeatedTest@ParameterizedTest或者@TestFactory注解的方法之后执行
  • @AfterAll 类似于JUnit 4的@AfterClass,表示使用了该注解的方法应该在当前类中所有使用了@Test@RepeatedTest@ParameterizedTest或者@TestFactory注解的方法之后执行,必须为static
  • @Disable 用于禁用一个测试类或测试方法,类似于JUnit 4的@Ignore
  • @ExtendWith 用于注册自定义扩展

3.编写单元测试

1)添加依赖

spring-boot-starter-test默认使用junit4,需要手动添加junit5依赖

		<!-- Junit 5 -->
		<dependency>
			<groupId>org.junit.jupiter</groupId>
			<artifactId>junit-jupiter-api</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.junit.jupiter</groupId>
			<artifactId>junit-jupiter-params</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.junit.jupiter</groupId>
			<artifactId>junit-jupiter-engine</artifactId>
			<scope>test</scope>
		</dependency>

2)代码编写

JUnit Jupiter附带了很多JUnit 4就已经存在的断言方法,并增加了一些适合与Java8 Lambda一起使用的断言。所有的JUnit Jupiter断言都是 org.junit.jupiter.api.Assertions 类中static方法。

package cn.swift.mapper;

import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.transaction.annotation.Transactional;

import cn.swift.model.User;

@ExtendWith(SpringExtension.class) //导入spring测试框架[2]
@SpringBootTest  //提供spring依赖注入
@Transactional  //事务管理,默认回滚,如果配置了多数据源记得指定事务管理器
@DisplayName("Test UserMapper")
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;
    
    private static User user;
    
    @BeforeAll //在所有测试方法前执行,只执行一次
    static void setUp() {
	user = new User();
	user.setUsername("TEST_USER");
	user.setPassword("123456");
	user.setEmail("test@gamil.com");
	user.setDescription("this is a user for test.");
    }
    
    @Test
    @DisplayName("Add user")
    void addUserTest() {
    //支持java8 lambda
	assertAll("Insert User Success.",
		() -> assertNotNull(userMapper.insertSelective(user)),
		() -> assertNotNull(user.getId()));
    }
    
    @Test
    @DisplayName("Delete user")
    void deleteUserTest() {
	assertEquals(0, userMapper.deleteByPrimaryKey(-1L));
    }
    
    @Test
    @DisplayName("Modify user")
    void modifyUserTest() {
	user.setId(-1L);
	assertEquals(0, userMapper.updateByPrimaryKeySelective(user));
    }
    
    @Test
    @DisplayName("Query user")
    void queryUserTest() {
	assertNull(userMapper.selectByPrimaryKey(-1L));
    }
}

执行结果
UserMapperTest

4.总结

上述代码只是演示了spring boot + junit最简单的使用,实际应用时可以做很多测试
如:

  • MockMvc 测试http请求
  • Mockito 模拟测试对象

强大的功能需要根据实际需求来选择使用。
演示代码地址:https://github.com/tsfans/spring-boot-scaffold

5.参考文献

[1] JUnit 5官方文档 https://sjyuan.cc/junit5/user-guide-cn/#3-编写测试
[2] Spring Boot 2官方文档 https://docs.spring.io/spring-boot/docs/2.1.0.RELEASE/reference/htmlsingle/#boot-features-testing

展开阅读全文

spring boot 单元测试出错

02-01

2018-02-01 14:08:03.005 WARN 34600 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1406, SQLState: 22001n2018-02-01 14:08:03.005 ERROR 34600 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : Data truncation: Data too long for column 'name' at row 1n2018-02-01 14:08:03.007 WARN 34600 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Warning Code: 1406, SQLState: HY000n2018-02-01 14:08:03.008 WARN 34600 --- [ main] o.h.engine.jdbc.spi.SqlExceptionHelper : Data too long for column 'name' at row 1n2018-02-01 14:08:03.019 INFO 34600 --- [ main] o.s.t.c.transaction.TransactionContext : Rolled back transaction for test context [DefaultTestContext@5a8e6209 testClass = ApplicationTests, testInstance = com.didispace.ApplicationTests@4f970963, testMethod = test@ApplicationTests, testException = org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.DataException: could not execute statement, mergedContextConfiguration = [MergedContextConfiguration@4b4523f8 testClass = ApplicationTests, locations = '', classes = 'class com.didispace.Application', contextInitializerClasses = '[]', activeProfiles = '', propertySourceLocations = '', propertySourceProperties = '', contextLoader = 'org.springframework.boot.test.SpringApplicationContextLoader', parent = [null]]].n2018-02-01 14:08:03.029 INFO 34600 --- [ Thread-2] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@20d28811: startup date [Thu Feb 01 14:07:59 GMT+08:00 2018]; root of context hierarchyn2018-02-01 14:08:03.035 INFO 34600 --- [ Thread-2] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'n 问答

没有更多推荐了,返回首页