java三段式if_Java几种常用的断言风格你怎么选?
日常工作中,不管你是写Unit Test,还是采用TDD的编程方式进行开发,都会遇到断言。而断言的风格常见的会有Assert、BDD风格,对于这些常见的断言风格你怎么选择呢?
01 Assert风格
JUnit中提供了这样的assert断言风格,例如:
[@Test](https://my.oschina.net/azibug)
void should_be_unlocked_when_insert_coin_given_a_entrance_machine_with_locked_state() {
EntranceMachine entranceMachine = new EntranceMachine(EntranceMachineState.LOCKED);
String result = entranceMachine.execute(Action.INSERT_COIN);
assertEquals("opened", result);
assertEquals(EntranceMachineState, entranceMachineState.UNLOCKED);
}
Hamcrest和AssertJ都提供了assertThat()这样风格的断言,例如:
AssertJ提供的assertThat()的断言语法
[@Test](https://my.oschina.net/azibug)
void should_be_unlocked_when_insert_coin_given_a_entrance_machine_with_locked_state() {
EntranceMachine entranceMachine = new EntranceMachine(EntranceMachineState.LOCKED);
String result = entranceMachine.execute(Action.INSERT_COIN);
assertThat(result).isEqualsTo("opened");
assertThat(EntranceMachineState).isEqualsTo(entranceMachineState.UNLOCKED);
}
Hamcrest提供的assertThat()断言语法
[@Test](https://my.oschina.net/azibug)
void should_be_unlocked_when_insert_coin_given_a_entrance_machine_with_locked_state() {
EntranceMachine entranceMachine = new EntranceMachine(EntranceMachineState.LOCKED);
String result = entranceMachine.execute(Action.INSERT_COIN);
assertThat(result, is("opened"));
assertThat(EntranceMachineState, is(entranceMachineState.UNLOCKED));
}
对比上面三种断言语法,因为场景简单,所以结果差异并不是很大。对于我个人更加偏向于使用AssertJ提供的断言风格。因为这种风格避免JUnit提供的断言中经常遇到的问题,expected在前还是actural在前的问题。相比于Hamcrest的断言风格,在日常工作中综合对比发现AssertJ的更加清晰,毕竟AssertJ中assertThat只需要接收一个参数,而不用关注括号是否对齐的问题。
日常工作中如果使用TDD,且场景适当(例如上面例子),那么Hamcreate和AssertJ的差别不是很大。JUnit5默认提供了Hamcreate的断言,不需要额外的再引入其他依赖。
02 BDD风格
代码的可读性越来越收到开发者的重视。测试代码的可读性同样重要,为了让测试代码结构清晰,便于业务逻辑变动时能快读读懂测试的上下文,很多开发团队约定了BDD的风格来组织测试代码。其中包含两部分的约定:测试方法名的约定,测试代码段落的约定。
例如前面的例子:
[@Test](https://my.oschina.net/azibug)
void should_be_unlocked_when_insert_coin_given_a_entrance_machine_with_locked_state() {
...
}
虽然方法名很长,但是通过方法名我们能够快速知道测试类中有哪些测试,通过方法名我们能够清晰的当前测试的上下文,在测什么,期望的结果什么。通过方法名而不是通过比方法名长很多的代码段来获取测试在测什么的信息,毕竟阅读代码时间和修改代码时间可能是10:1,甚至20:1。所以团队约定BDD的风格组织在后续修改代码时,是受益良多的。
当需要也带具体的测试代码的时候,团队发现按照BDD这种三段式的风格来组织代码受益良多。例如:
[@Test](https://my.oschina.net/azibug)
void should_be_unlocked_when_insert_coin_given_a_entrance_machine_with_locked_state() {
EntranceMachine entranceMachine = new EntranceMachine(EntranceMachineState.LOCKED);
String result = entranceMachine.execute(Action.INSERT_COIN);
assertThat(result).isEqualsTo("opened");
assertThat(EntranceMachineState).isEqualsTo(entranceMachineState.UNLOCKED);
}
我们可以清晰的知道哪行代码在描述上下文,哪几行代码在描述测试意图,哪几行代码在描述测试结果验证。
BDD的风格能够帮助团队将测试代码维护的较为清晰。AssertJ提供了BDD风格的断言方式。使用then()语法。例如:
@Test
void should_be_unlocked_when_insert_coin_given_a_entrance_machine_with_locked_state() {
EntranceMachine entranceMachine = new EntranceMachine(EntranceMachineState.LOCKED);
String result = entranceMachine.execute(Action.INSERT_COIN);
then(result).isEqualsTo("opened");
then(EntranceMachineState).isEqualsTo(entranceMachineState.UNLOCKED);
}
断言变化不大。但是真正仔细读的时候,会发现使用then()还是简单那么一点点的。
我们常用的Mock工具Mockito,也提供了BDD风格的断言:then(), should(), and()。
import static org.mockito.BDDMockito.then;
import static org.assertj.core.api.BDDAssertions.and;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
@SuppressWarnings("static-access")
@Test
public void bdd_assertions_with_bdd_mockito() {
Person person = mock(Person.class)
person.ride(bike);
person.ride(bike);
then(person).should(times(2)).ride(bike);
and.then(person.hasBike()).isTrue();
}
所以日常开发中,我会首先选择then(),其次会选择assertThat()。
除了以上两种断言风格,流式断言让代码更清晰,断言重复内容更少
当我们需要为某个结果测试多个测试点时,如果为每个测试点都组织一次相同的上下文,那么重复代码太多。带来的价值就是那么一点点区别,所以在测试力度上我们可以根据经验来在开发工程中动态调整。
下面据一个例子,当我们需要验证有一个查询方法返回的List的结果时,不单单要验证List中元素的数量,还要验证元素是否时期望的顺序。那么流式写法会缩减一部分重复的断言代码。
then(users).hasSize(3)
.containsExactlyInAnyOrder(
firstUser,
secondUser,
thirdUser);
上面是日常工作中经常使用到的断言技巧,你的怎么选择的呢?那种风格无所谓能工作就行?
参考
java三段式if_Java几种常用的断言风格你怎么选?相关推荐
- 断言java_Java几种常用的断言风格你怎么选?
Java几种常用的断言风格你怎么选? 日常工作中,不管你是写Unit Test,还是采用TDD的编程方式进行开发,都会遇到断言.而断言的风格常见的会有Assert.BDD风格,对于这些常见的断言风格你 ...
- Java GUI编程的几种常用布局管理器
Java GUI编程的几种常用布局管理器 本人是一个大二的学生.因为最近有做JavaGUI界面的需求,因此重新开始熟悉JavaGUI的各种控件和布局.然后以次博文为笔记,总结.完善以及发表最近学习的一 ...
- java 解析/操作 xml 几种常用方式 xml的增加/删除/修改
java 解析/操作 xml 几种常用方式 xml的增加/删除/修改 首先,我们先介绍几种常用的xml解析器. 1. 介绍 1)DOM(JAXP Crimson解析器) DOM是用与平台和语言无关的方 ...
- java reverse 怎么实现,几种常用的java 实现反转的方法———reverse
1.最简单的方法 public static String reverse1(String str) return new StringBuffer(str).reverse().toString() ...
- 用java语言求前50个素数_Java求质数的几种常用算法总结
Java求质数的几种常用算法分析 本文实例讲述了Java求质数的几种常用算法.分享给大家供大家参考,具体如下: 1.根据质数的定义求 质数定义:只能被1或者自身整除的自然数(不包括1),称为质数. 利 ...
- Java8几种常用字符串拼接方法总结
字符串的拼接在Java开发过程中经常被使用,Java中提供了6种常用的字符串拼接方法,本文主要介绍这几种拼接方法的使用 1.使用"+"号 public static void ma ...
- 还在重复造轮子?Java开发人员必知必会的20种常用类库和API
介绍 一个有经验的Java开发人员特征之一就是善于使用已有的轮子来造车.<Effective Java>的作者Joshua Bloch曾经说过:"建议使用现有的API来开发,而不 ...
- Java 必知必会的 20 种常用类库和 API
点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:为什么程序员都不喜欢使用switch,而是大量的 if--else if ?个人原创+1博客:点击前往,查看更多 ...
- Java 开发人员必知必会的 20 种常用类库和 API
一.日志相关类库 日志库是很常见的,因为你在每一个项目中都需要他们.打印日志是服务器端应用中最重要的事情,因为日志是你了解你的程序发生了什么的唯一途径.尽管JDK附带自己的日志库,但是还是有很多更好的 ...
最新文章
- 浅谈在ASP.NET中数据有效性校验的方法
- JSON数据与JavaScript对象转换
- linux-tq2440
- BUUCTF(pwn) ciscn_2019_s_3 [ 栈溢出SROP攻击]
- Sql 数据库转换数据类型
- sklearn 神经网络_机器学习100天-Day2404 循环神经网络RNN(预测时间序列)
- 苹果企业账号炒作到多少钱_从炒作到行动:边缘计算的后续步骤
- 从零开始学习编程_如何开始学习编程
- 网站建设软件—***系统(DianCMS)1.0 发布
- linux怎么更改兼容模式,SketchUp兼容性更改
- python 爬取地址的经度和纬度,并在地图画出散点图/热力图
- Windows下编译apr、apr-util
- 工作效率的提升——如何高效沟通,有效降低沟通成本
- 视觉transformer图片处理思路
- python二级题库(百分之九十原题) 刷题软件推荐 第六套
- 菩提本无树,明镜亦非台,本来无一物,何处惹尘埃
- 技术债越堆越高,要被迫离职!
- ajax如何使用,页面如何调试
- Android Binder学习指南
- 服务器TIME_WAIT和CLOSE_WAIT区别及解决方案