目录

添加依赖与配置

ApplicationContext测试

Environment测试

MockBean测试

Controller测试

情况一

情况二

方法一

方法二


本文将对在Springboot中如何使用Junit进行单元测试进行简单示例和介绍,项目的完整目录层次如下图所示。

添加依赖与配置

为了保证测试的完整性,本工程POM文件中除引入Junit单元测试依赖外,还额外引入了用来测试JDBC和Controller的JPA和WEB依赖。


  1. <parent>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-parent</artifactId>
  4. <version>1.5.6.RELEASE</version>
  5. </parent>
  6. <dependencies>
  7. <!-- 添加MySQL依赖 -->
  8. <dependency>
  9. <groupId>mysql</groupId>
  10. <artifactId>mysql-connector-java</artifactId>
  11. </dependency>
  12. <!-- 添加JDBC依赖 -->
  13. <dependency>
  14. <groupId>org.springframework.boot</groupId>
  15. <artifactId>spring-boot-starter-data-jpa</artifactId>
  16. </dependency>
  17. <dependency>
  18. <groupId>org.springframework.boot</groupId>
  19. <artifactId>spring-boot-starter-web</artifactId>
  20. </dependency>
  21. <!-- 引入单元测试依赖 -->
  22. <dependency>
  23. <groupId>org.springframework.boot</groupId>
  24. <artifactId>spring-boot-starter-test</artifactId>
  25. <scope>test</scope>
  26. </dependency>
  27. </dependencies>

同时,在src/main/resources目录下添加核心配置文件application.properties,内容如下。


  1. #########################################################
  2. ### Spring DataSource -- DataSource configuration ###
  3. #########################################################
  4. spring.datasource.url=jdbc:mysql://localhost:3306/dev1?useUnicode=true&characterEncoding=utf8
  5. spring.datasource.driverClassName=com.mysql.jdbc.Driver
  6. spring.datasource.username=root
  7. spring.datasource.password=123456
  8. #########################################################
  9. ### Java Persistence Api -- Spring jpa configuration ###
  10. #########################################################
  11. # Specify the DBMS
  12. spring.jpa.database = MYSQL
  13. # Show or not log for each sql query
  14. spring.jpa.show-sql = true
  15. # Hibernate ddl auto (create, create-drop, update)
  16. spring.jpa.hibernate.ddl-auto = update
  17. # Naming strategy
  18. #[org.hibernate.cfg.ImprovedNamingStrategy #org.hibernate.cfg.DefaultNamingStrategy]
  19. spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
  20. # stripped before adding them to the entity manager)
  21. spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

ApplicationContext测试

在Springboot中使用Junit进行单元测试的方法很简单,只需要在编写的单元测试类上添加两个注解:@RunWith(SpringRunner.class)和@SpringBootTest。


  1. @RunWith(SpringRunner.class) // 等价于使用 @RunWith(SpringJUnit4ClassRunner.class)
  2. @SpringBootTest(classes = { MyApplication.class, TestConfig.class })
  3. public class ApplicationContextTest {
  4. @Autowired
  5. private ApplicationContext context;
  6. @Autowired
  7. private UserDao userDao;
  8. @Test
  9. public void testUserDao() {
  10. userDao.addUser(18, "pengjunlee");
  11. }
  12. @Test
  13. public void testConfiguration() {
  14. Runnable bean = context.getBean(Runnable.class);
  15. Assert.assertNotNull(bean);
  16. bean.run();
  17. }
  18. }

UserDao定义如下。


  1. @Repository
  2. public class UserDao {
  3. @Autowired
  4. private JdbcTemplate jdbcTemplate;
  5. @Transactional
  6. public void addUser(Integer userAge, String userName) {
  7. String sql = "insert into tbl_user (age,name) values ('" + userAge + "','" + userName + "');";
  8. jdbcTemplate.execute(sql);
  9. }
  10. }

TestConfig定义如下。


  1. /**
  2. * @TestConfiguration注解的配置内的Bean仅在测试时装配
  3. */
  4. @TestConfiguration
  5. public class TestConfig {
  6. @Bean
  7. public Runnable createRunnable(){
  8. return ()->{
  9. System.out.println("This is a test Runnable bean...");
  10. };
  11. }
  12. }

提示:@SpringBootTest注解的classes可以指定用来加载Spring容器所使用的配置类,@TestConfiguration注解修饰的配置类内的Bean仅在测试的时候才会装配。

Environment测试

我们可以通过@SpringBootTest注解的properties属性向Environment中设置新的属性,也可以通过使用EnvironmentTestUtils工具类来向ConfigurableEnvironment中添加新的属性。


  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest(properties = { "app.token=pengjunlee" })
  3. public class EnvironmentTest {
  4. @Autowired
  5. private Environment env;
  6. @Autowired
  7. private ConfigurableEnvironment cenv;
  8. @Before
  9. public void init() {
  10. EnvironmentTestUtils.addEnvironment(cenv, "app.secret=55a4b77eda");
  11. }
  12. @Test
  13. public void testEnvironment() {
  14. System.out.println(env.getProperty("spring.datasource.url"));
  15. Assert.assertEquals("pengjunlee", env.getProperty("app.token"));
  16. Assert.assertEquals("55a4b77eda", cenv.getProperty("app.secret"));
  17. }
  18. @Test
  19. @Ignore // 忽略测试方法
  20. public void testIgnore() {
  21. System.out.println("你看不见我...");
  22. }
  23. }

扩展:Junit测试用例执行顺序:@BeforeClass ==> @Before ==> @Test ==> @After ==> @AfterClass 。

注意:在使用Junit对Spring容器进行单元测试时,若在src/test/resources 目录下存在核心配置文件,Spring容器将会只加载src/test/resources 目录下的核心配置文件,而不再加载src/main/resources 目录下的核心配置文件。

MockBean测试

我们可以通过@MockBean注解来对那些未添加实现的接口进行模拟测试,预先设定好调用方法期待的返回值,然后再进行测试。

例如,有如下的IUserService接口,定义了一个getUserAge()方法用来根据用户的ID来查询用户的年龄。


  1. public interface IUserService {
  2. Integer getUserAge(Long userId);
  3. }

使用@MockBean来对IUserService接口进行模拟测试,测试代码如下。


  1. @RunWith(SpringRunner.class)
  2. public class MockBeanTest {
  3. @MockBean
  4. private IUserService userService;
  5. @SuppressWarnings("unchecked")
  6. @Test(expected = NullPointerException.class)
  7. public void testMockBean() {
  8. BDDMockito.given(userService.getUserAge(2L)).willReturn(Integer.valueOf(18));
  9. BDDMockito.given(userService.getUserAge(0L)).willReturn(Integer.valueOf(0));
  10. BDDMockito.given(userService.getUserAge(null)).willThrow(NullPointerException.class);
  11. Assert.assertEquals(Integer.valueOf(18), userService.getUserAge(2L));
  12. Assert.assertEquals(Integer.valueOf(0), userService.getUserAge(0L));
  13. Assert.assertEquals(Integer.valueOf(0), userService.getUserAge(null));
  14. }
  15. }

Controller测试

在Springboot中可以通过TestRestTemplate和MockMvc来对Controller进行测试,有以下两种情况。

情况一

Controller中未装配任何其他Spring容器中的Bean,例如下面这个控制器。


  1. @RestController
  2. @RequestMapping("/user")
  3. public class UserController01 {
  4. @GetMapping("/home")
  5. public String homeUser(@RequestParam(name = "name", required = true) String userName) {
  6. if (null == userName || userName.trim() == "") {
  7. return "you are nobody...";
  8. }
  9. return "This is " + userName + "'s home...";
  10. }
  11. }

此时无需启动Spring容器,可直接使用MockMvc来对Controller进行模拟测试,测试代码如下。


  1. @RunWith(SpringRunner.class)
  2. @WebMvcTest(controllers = { UserController01.class })
  3. public class ControllerTest01 {
  4. @Autowired
  5. private MockMvc mvc;
  6. @Test
  7. public void testAddUser() throws Exception {
  8. mvc.perform(MockMvcRequestBuilders.get("/user/home").param("name", ""))
  9. .andExpect(MockMvcResultMatchers.status().isOk())
  10. .andExpect(MockMvcResultMatchers.content().string("you are nobody..."));
  11. mvc.perform(MockMvcRequestBuilders.get("/user/home").param("name", "pengjunlee"))
  12. .andExpect(MockMvcResultMatchers.status().isOk())
  13. .andExpect(MockMvcResultMatchers.content().string("This is pengjunlee's home..."));
  14. }
  15. }

情况二

Controller中需装配其他Spring容器中的Bean,例如下面这个控制器。


  1. @RestController
  2. @RequestMapping("/user")
  3. public class UserController02 {
  4. @Autowired
  5. private UserDao userDao;
  6. @GetMapping("/add")
  7. public String addUser(@RequestParam(name = "age", required = false, defaultValue = "0") Integer userAge,
  8. @RequestParam(name = "name", required = true) String userName) {
  9. if (userAge <= 0 || null == userName || userName.trim() == "") {
  10. return "0";
  11. }
  12. userDao.addUser(userAge, userName);
  13. return "1";
  14. }
  15. }

此时除了要启动Spring容器,还需要启动内嵌的WEB环境,有以下两种方法。

方法一

利用TestRestTemplate进行测试。


  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
  3. public class ControllerTest02 {
  4. @Autowired
  5. private TestRestTemplate template;
  6. @Test
  7. public void testAddUser() {
  8. String result1 = template.getForObject("/user/add?name=pengjunlee", String.class);
  9. Assert.assertEquals("0", result1);
  10. String result2 = template.getForObject("/user/add?age=20&name=Tracy", String.class);
  11. Assert.assertEquals("1", result2);
  12. }
  13. }

方法二

利用MockMvc进行测试。


  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
  3. @AutoConfigureMockMvc
  4. public class ControllerTest03 {
  5. @Autowired
  6. private MockMvc mvc;
  7. @Test
  8. public void testAddUser() throws Exception {
  9. mvc.perform(MockMvcRequestBuilders.get("/user/add").param("name", ""))
  10. .andExpect(MockMvcResultMatchers.status().isOk())
  11. .andExpect(MockMvcResultMatchers.content().string("0"));
  12. mvc.perform(MockMvcRequestBuilders.get("/user/add").param("age", "22").param("name", "pengjunlee"))
  13. .andExpect(MockMvcResultMatchers.status().isOk())
  14. .andExpect(MockMvcResultMatchers.content().string("1"));
  15. }
  16. }

本文项目源码已上传至CSDN,资源地址:https://download.csdn.net/download/pengjunlee/10394302

原文地址:https://blog.csdn.net/pengjunlee/article/details/80206615

SpringBoot重点详解--使用Junit进行单元测试的更多相关文章

  1. springboot配置详解

    springboot配置详解 Author:SimpleWu properteis文件属性参考大全 springboot默认加载配置 SpringBoot使用两种全局的配置文件,全局配置文件可以对一些 ...

  2. springboot项目--传入参数校验-----SpringBoot开发详解(五)--Controller接收参数以及参数校验----https://blog.csdn.net/qq_31001665/article/details/71075743

    https://blog.csdn.net/qq_31001665/article/details/71075743 springboot项目--传入参数校验-----SpringBoot开发详解(五 ...

  3. SpringBoot @ConfigurationProperties详解

    文章目录 简介 添加依赖关系 一个简单的例子 属性嵌套 @ConfigurationProperties和@Bean 属性验证 属性转换 自定义Converter SpringBoot @Config ...

  4. Spring Boot2 系列教程 (二) | 第一个 SpringBoot 工程详解

    微信公众号:一个优秀的废人 如有问题或建议,请后台留言,我会尽力解决你的问题. 前言 哎呦喂,按照以往的惯例今天周六我的安排应该是待在家学学猫叫啥的.但是今年这种日子就可能一去不复返了,没法办法啊.前 ...

  5. SpringBoot——配置文件详解【五】

    前言 SpringBoot的配置文件 配置文件 SpringBoot使用一个全局的配置文件,配置文件名是固定的. application.properties application.yml 配置文件 ...

  6. Go语言学习之8 goroutine详解、定时器与单元测试

    主要内容: 1.Goroutine2. Chanel3. 单元测试 1. Goroutine Go 协程(Goroutine)(轻量级的线程,开线程没有数量限制).   (1)进程和线程 A. 进程是 ...

  7. matlab考试重点详解

    此帖是根据期末考试复习重点补充完成, 由于使用word编辑引用图片和链接略有不便, 所以开此贴供复习及学习使用.侵删 复习要点 第一章 Matlab的基本概念,名称的来源,基本功能,帮助的使用方法 1 ...

  8. Springboot 启动详解

    1.前言 最近一直在看Springboot和springcloud代码,看了将近20多天,对这两个系统的认知总算是入了门.后续应该会有一个系列的文章,本文就先从Springboot的启动入手. 2.容 ...

  9. 2.SpringBoot HelloWorld详解

    1.POM文件 父项目 <parent> <groupId>org.springframework.boot</groupId> <artifactId> ...

随机推荐

  1. sencha touch 入门学习资料大全

    现在sencha touch已经更新到2.3.1版本了 重新整理一下资料 官方网站:http://www.sencha.com/products/touch/ 在线文档:http://docs.sen ...

  2. 扫雷游戏 NOIP(入门)

    题目描述: 扫雷游戏是一款十分经典的单机小游戏.它的精髓在于,通过已翻开格子所提示的周围格地雷数,来判断未翻开格子里是否是地雷. 现在给出n行m列的雷区中的地雷分布,要求计算出每个非地雷格的周围格地雷 ...

  3. LaTeX中常用数学符号总结

    博主一些小小的总结,以后会继续更的. 某个传送门. ⎝⎛•‿•⎞⎠⎝⎛•‿•⎞⎠⎝⎛•‿•⎞⎠ 1.左右一个$: 1+1=2 $1+1=2$ ($3$及以后的都需要$) 2.左右两个$: 1+1=2 ...

  4. 【点分治】luoguP2664 树上游戏

    应该是一道中等难度的点分?麻烦在一些细节. 题目描述 lrb有一棵树,树的每个节点有个颜色.给一个长度为n的颜色序列,定义s(i,j) 为i 到j 的颜色数量.以及 现在他想让你求出所有的sum[i] ...

  5. matplotlib绘图(四)

    控制文字属性的方法: 所有的方法都会返回一个matplotlib.text.Text对象  文本注释: annnotate() xy参数设置箭头指示的位置,xytext参数设置注释文字的位置 arro ...

  6. Linux安装OpenCV

    sudo apt-get update sudo apt-get install git git clone https://github.com/jayrambhia/Install-OpenCV ...

  7. 循环字典进行操作时出现:RuntimeError: dictionary changed size during iteration的解决方案

    在做对员工信息增删改查这个作业时,有一个需求是通过用户输入的id删除用户信息.我把用户信息从文件提取出来储存在了字典里,其中key是用户id,value是用户的其他信息.在循环字典的时候,当用户id和 ...

  8. UVa - 12096 集合栈计算机(STL)

    [题意] 有一个专门为了集合运算而设计的“集合栈”计算机.该机器有一个初始为空的栈,并且支持以下操作:PUSH:空集“{}”入栈DUP:把当前栈顶元素复制一份后再入栈UNION:出栈两个集合,然后把两 ...

  9. strcpy和strncpy用法和区别

    1. strcpy函数:顾名思义字符串复制函数:原型:extern char *strcpy(char *dest,char *src); 功能:把从src地址开始且含有NULL结束符的字符串赋值到以 ...

  10. HDU 2852 KiKi's K-Number 主席树

    题意: 要求维护一个数据结构,支持下面三种操作: \(0 \, e\):插入一个值为\(e\)的元素 \(1 \, e\):删除一个值为\(e\)的元素 \(2 \, a \, k\):查询比\(a\ ...