Junit这种老技术,现在又拿出来说,不为别的,某种程度上来说,更是为了要说明它在项目中的重要性。
凭本人的感觉和经验来说,在项目中完全按标准都写Junit用例覆盖大部分业务代码的,应该不会超过一半。

刚好前段时间写了一些关于SpringBoot的帖子,正好现在把Junit再拿出来从几个方面再说一下,也算是给一些新手参考了。

那么先简单说一下为什么要写测试用例
1. 可以避免测试点的遗漏,为了更好的进行测试,可以提高测试效率
2. 可以自动测试,可以在项目打包前进行测试校验
3. 可以及时发现因为修改代码导致新的问题的出现,并及时解决

那么本文从以下几点来说明怎么使用Junit,Junit4比3要方便很多,细节大家可以自己了解下,主要就是版本4中对方法命名格式不再有要求,不再需要继承TestCase,一切都基于注解实现。

1、SpringBoot Web项目中中如何使用Junit

创建一个普通的Java类,在Junit4中不再需要继承TestCase类了。
因为我们是Web项目,所以在创建的Java类中添加注解:

@RunWith(SpringJUnit4ClassRunner.class) // SpringJUnit支持,由此引入Spring-Test框架支持!
@SpringApplicationConfiguration(classes = SpringBootSampleApplication.class) // 指定我们SpringBoot工程的Application启动类
@WebAppConfiguration // 由于是Web项目,Junit需要模拟ServletContext,因此我们需要给我们的测试类加上@WebAppConfiguration。 

接下来就可以编写测试方法了,测试方法使用@Test注解标注即可。
在该类中我们可以像平常开发一样,直接@Autowired来注入我们要测试的类实例。
下面是完整代码:

package org.springboot.sample;import static org.junit.Assert.assertArrayEquals;import org.junit.Test;
import org.junit.runner.RunWith; import org.springboot.sample.service.StudentService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; /** * * @author 单红宇(365384722) * @myblog http://blog.csdn.net/catoop/ * @create 2016年2月23日 */ @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = SpringBootSampleApplication.class) @WebAppConfiguration public class StudentTest { @Autowired private StudentService studentService; @Test public void likeName() { assertArrayEquals( new Object[]{ studentService.likeName("小明2").size() > 0, studentService.likeName("坏").size() > 0, studentService.likeName("莉莉").size() > 0 }, new Object[]{ true, false, true } ); // assertTrue(studentService.likeName("小明2").size() > 0); } } 

接下来,你需要新增无数个测试类,编写无数个测试方法来保障我们开发完的程序的有效性。

2、Junit基本注解介绍

//在所有测试方法前执行一次,一般在其中写上整体初始化的代码
@BeforeClass

//在所有测试方法后执行一次,一般在其中写上销毁和释放资源的代码 
@AfterClass

//在每个测试方法前执行,一般用来初始化方法(比如我们在测试别的方法时,类中与其他测试方法共享的值已经被改变,为了保证测试结果的有效性,我们会在@Before注解的方法中重置数据)
@Before

//在每个测试方法后执行,在方法执行完成后要做的事情
@After

// 测试方法执行超过1000毫秒后算超时,测试将失败
@Test(timeout = 1000)

// 测试方法期望得到的异常类,如果方法执行没有抛出指定的异常,则测试失败
@Test(expected = Exception.class)

// 执行测试时将忽略掉此方法,如果用于修饰类,则忽略整个类
@Ignore("not ready yet")
@Test

@RunWith
在JUnit中有很多个Runner,他们负责调用你的测试代码,每一个Runner都有各自的特殊功能,你要根据需要选择不同的Runner来运行你的测试代码。
如果我们只是简单的做普通Java测试,不涉及Spring Web项目,你可以省略@RunWith注解,这样系统会自动使用默认Runner来运行你的代码。

3、参数化测试

Junit为我们提供的参数化测试需要使用 @RunWith(Parameterized.class)
然而因为Junit 使用@RunWith指定一个Runner,在我们更多情况下需要使用@RunWith(SpringJUnit4ClassRunner.class)来测试我们的Spring工程方法,所以我们使用assertArrayEquals 来对方法进行多种可能性测试便可。

下面是关于参数化测试的一个简单例子:

package org.springboot.sample;import static org.junit.Assert.assertTrue;import java.util.Arrays; import java.util.Collection; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; @RunWith(Parameterized.class) public class ParameterTest { private String name; private boolean result; /** * 该构造方法的参数与下面@Parameters注解的方法中的Object数组中值的顺序对应 * @param name * @param result */ public ParameterTest(String name, boolean result) { super(); this.name = name; this.result = result; } @Test public void test() { assertTrue(name.contains("小") == result); } /** * 该方法返回Collection * * @return * @author SHANHY * @create 2016年2月26日 */ @Parameters public static Collection<?> data(){ // Object 数组中值的顺序注意要和上面的构造方法ParameterTest的参数对应 return Arrays.asList(new Object[][]{ {"小明2", true}, {"坏", false}, {"莉莉", false}, }); } } 

4、打包测试
正常情况下我们写了5个测试类,我们需要一个一个执行。
打包测试,就是新增一个类,然后将我们写好的其他测试类配置在一起,然后直接运行这个类就达到同时运行其他几个测试的目的。

代码如下:

@RunWith(Suite.class)
@SuiteClasses({ATest.class, BTest.class, CTest.class})
public class ABCSuite {// 类中不需要编写代码
}

5、使用Junit测试HTTP的API接口
我们可以直接使用这个来测试我们的Rest API,如果内部单元测试要求不是很严格,我们保证对外的API进行完全测试即可,因为API会调用内部的很多方法,姑且把它当做是整合测试吧。

下面是一个简单的例子:

package org.springboot.sample;import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;import java.util.regex.Matcher;
import java.util.regex.Pattern; import org.hamcrest.Matchers; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.boot.test.TestRestTemplate; import org.springframework.boot.test.WebIntegrationTest; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; /** * * @author 单红宇(365384722) * @myblog http://blog.csdn.net/catoop/ * @create 2016年2月23日 */ @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = SpringBootSampleApplication.class) //@WebAppConfiguration // 使用@WebIntegrationTest注解需要将@WebAppConfiguration注释掉 @WebIntegrationTest("server.port:0")// 使用0表示端口号随机,也可以具体指定如8888这样的固定端口 public class HelloControllerTest { private String dateReg; private Pattern pattern; private RestTemplate template = new TestRestTemplate(); @Value("${local.server.port}")// 注入端口号 private int port; @Test public void test3(){ String url = "http://localhost:"+port+"/myspringboot/hello/info"; MultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>(); map.add("name", "Tom"); map.add("name1", "Lily"); String result = template.postForObject(url, map, String.class); System.out.println(result); assertNotNull(result); assertThat(result, Matchers.containsString("Tom")); } } 

6、捕获输出
使用 OutputCapture 来捕获指定方法开始执行以后的所有输出,包括System.out输出和Log日志。
OutputCapture 需要使用@Rule注解,并且实例化的对象需要使用public修饰,如下代码:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SpringBootSampleApplication.class)
//@WebAppConfiguration // 使用@WebIntegrationTest注解需要将@WebAppConfiguration注释掉 @WebIntegrationTest("server.port:0")// 使用0表示端口号随机,也可以具体指定如8888这样的固定端口 public class HelloControllerTest { @Value("${local.server.port}")// 注入端口号 private int port; private static final Logger logger = LoggerFactory.getLogger(StudentController.class); @Rule // 这里注意,使用@Rule注解必须要用public public OutputCapture capture = new OutputCapture(); @Test public void test4(){ System.out.println("HelloWorld"); logger.info("logo日志也会被capture捕获测试输出"); assertThat(capture.toString(), Matchers.containsString("World")); } } 

关于Assert类中的一些断言方法,都很简单,本文不再赘述。

但是在新版的Junit中,assertEquals 方法已经被废弃,它建议我们使用assertArrayEquals,旨在让我们测试一个方法的时候多传几种参数进行多种可能性测试。

转自:https://yq.aliyun.com/articles/6925

转载于:https://www.cnblogs.com/xujanus/p/5664436.html

spring boot单元测试(转)相关推荐

  1. 保姆级教程:Spring Boot 单元测试

    作者 | 小名同学 来源 | https://eamonyin.blog.csdn.net/ 一. 单元测试的概念 概念: 单元测试(unit testing),是指对软件中的最小可测试单元进行检查和 ...

  2. spring boot单元测试

    做一个稳健的开发,写一首漂亮的单元测试是少不了的 首先要分清几个概念:测试方法.测试类.测试集.测试运行器. 测试方法就是用 @Test 注解的一些函数. 测试类是包含一个或多个测试方法的一个 XxT ...

  3. Spring Boot 单元测试详解+实战教程

    转载自   Spring Boot 单元测试详解+实战教程 Spring Boot 的测试类库 Spring Boot 提供了许多实用工具和注解来帮助测试应用程序,主要包括以下两个模块. spring ...

  4. Spring Boot 单元测试二三事

    本文翻译自:https://reflectoring.io/unit-... 原文作者:Tom Hombergs 译文原地址:https://weyunx.com/2019/02/04... 写好单元 ...

  5. spring boot 单元测试_spring-boot-plus1.2.0-RELEASE发布-快速打包-极速部署-在线演示

    spring-boot-plus spring-boot-plus 集成spring boot常用开发组件的后台快速开发脚手架 Purpose 每个人都可以独立.快速.高效地开发项目! Everyon ...

  6. Spring Boot————单元测试

    引言 由于spring boot在启动时通常会先行启动一些内置的组件,比如tomcat.因此,spring boot的测试类一般需要加一些简单的注解. 一.添加依赖 <dependency> ...

  7. Spring Boot单元测试入门实战之关于JUnit

    在我们开发Web应用时,经常会直接去观察结果进行测试.虽然也是一种方式,但是并不严谨. 作为开发者编写测试代码来测试自己所写的业务逻辑,以提高代码的质量.降低错误方法的概率以及进行性能测试等.而开发者 ...

  8. spring boot 单元测试的使用和一些坑

    1. 背景 在每次使用https://start.spring.io/ 创建spring boot后,都会发现它的单元测试好像有点不太一样,好像是用的junit5,但是我看的pom文件那个测试依赖太长 ...

  9. spring boot 单元测试报错 ,nacos discover未注册进服务中心

    1. 单元测试类与启动类 包路径不一致 java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you ...

最新文章

  1. sql server 查看对象最后修改时间
  2. Oracle timestamp 转换 date
  3. 目标检测--Feature Pyramid Networks for Object Detection
  4. SSMS2008插件开发(3)--部署调试SSMS2008插件
  5. python简单代码hello-实现简单的hello/hi程序——python
  6. 匿名内部类的使用实例
  7. 2.9-mysql主从配置-3
  8. android listview 异步加载图片并防止错位
  9. 澜起科技云计算服务器_服务器严重缺货!云应用大爆发!云计算正强势起爆(附龙头)...
  10. 苹果app商品定价_【知乎问答】苹果 App Store 新推出的 1 元或 3 元定价对开发者有什么影响?...
  11. 深度linux桌面启动器,在Deepin桌面系统启动器中创建“我的世界”启动项
  12. Event.ADDED_TO_STAGE的本质
  13. Python说文解字_杂谈07
  14. 基于SSM的高校后勤管理系统Java项目
  15. 【Android】Android签名:pem和pk8转化为keystore,jks
  16. 【论文】写毕业论文过程中遇到的问题及解决方式记录
  17. 24个足以改变事业的商业妙想
  18. Docker查看container的详细信息啥的*
  19. RX 6600XT vs RTX 2060Super 显卡对比
  20. 如何利用实验室信息管理系统LIMS轻松通过CNAS评审?

热门文章

  1. ubuntu 18.04 设置中文输入法
  2. 产品经理为什么越来越不值钱?不懂数据,只能尴尬退场
  3. FineBI与FineReport对比
  4. 就数据平台建设,80%的500强企业都有一个共性
  5. html几个数据包,报文和数据包的区别
  6. 单链表删除指定节点c语言,在单链表删除指定节点之后的节点
  7. mysql锁的一些理解简书_MySQL锁的基本概念
  8. python初级第三库(人工智能,web解析,人机交互)
  9. python不等于缺陷
  10. ajax显示失败信息,javascript