编写JUnit测试的另一种方法(Jasmine方法)

最近,我为一个小型个人项目编写了很多Jasmine测试。 我花了一些时间才终于感到正确地完成了测试。 此后,当我切换回JUnit测试时,我总是很难过。 出于某种原因,JUnit测试不再那么好,我想知道是否有可能以类似于Jasmine的方式编写JUnit测试。

Jasmine是受RSpec (Ruby BDD测试框架)启发的流行JavaScript行为驱动开发测试框架。

一个简单的茉莉花测试如下所示:

describe('AudioPlayer tests', function() {var player;beforeEach(function() {player = new AudioPlayer();});it('should not play any track after initialization', function() {expect(player.isPlaying()).toBeFalsy();});...
});

第一行中的describe()函数调用使用Description AudioPlayer tests创建一个新的测试套件。 在测试套件中,我们可以使用it()创建测试(在Jasmine中称为specs)。 在这里,我们检查创建新的AudioPlayer的isPlaying()方法是否返回false。
AudioPlayer实例。

用JUnit编写的相同测试如下所示:

public class AudioPlayerTest {private AudioPlayer audioPlayer;@Before public void before() {audioPlayer = new AudioPlayer();}@Testvoid notPlayingAfterInitialization() {assertFalse(audioPlayer.isPlaying());}...
}

我个人认为Jasmine测试与JUnit版本相比更具可读性。 在Jasmine中,对测试没有任何影响的唯一噪音是括号和function关键字。 其他所有内容都包含一些有用的信息。

在阅读JUnit测试时,我们可以忽略诸如void,访问修饰符(私有,公共,..),注释和不相关的方法名称(如以@Before注释的方法名称)之类的关键字。 除此之外,以驼峰案例方法名称编码的测试描述不太好阅读。

除了提高可读性外,我真的很喜欢Jasmine嵌套测试套件的功能。

让我们来看一个更长的示例:

describe('AudioPlayers tests', function() {var player;beforeEach(function() {player = new AudioPlayer();});describe('when a track is played', function() {var track;beforeEach(function() {track = new Track('foo/bar.mp3')player.play(track);});it('is playing a track', function() {expect(player.isPlaying()).toBeTruthy();});it('returns the track that is currently played', function() {expect(player.getCurrentTrack()).toEqual(track);});});...
});

在这里,我们创建了一个子测试套件,负责测试AudioPlayer播放曲目时的行为。 内部的beforeEach()调用用于为子测试套件内的所有测试设置通用的前提条件。

相反,在JUnit中为多个(但不是全部)测试共享通用的前提条件有时会变得很麻烦。 当然,在测试中复制设置代码是不好的,因此我们为此创建了额外的方法。 为了在设置方法和测试方法之间共享数据(如上面示例中的track变量),我们必须使用成员变量(范围要大得多)。

另外,我们应确保将具有类似前提条件的测试分组在一起,以避免需要阅读整个测试类来查找特定情况下的所有相关测试。 或者我们可以将事情分成多个较小的类。 但是,然后我们可能必须在这些类之间共享设置代码……

如果我们查看Jasmine测试,就会发现该结构是通过调用全局函数(例如describe(),it(),…)并传递描述性字符串和匿名函数来定义的。

有了Java 8,我们有了Lambdas,所以我们可以做同样的事情吗?

是的,我们可以在Java 8中编写如下代码:

public class AudioPlayerTest {private AudioPlayer player;public AudioPlayerTest() {describe("AudioPlayer tests", () -> {beforeEach(() -> {player = new AudioPlayer();});it("should not play any track after initialization", () -> {expect(player.isPlaying()).toBeFalsy();});});}
}

如果我们暂时假设describe(),beforeEach(),it()和Expect()是采用适当参数的静态导入方法,则至少可以编译。 但是,我们应该如何进行这种测试?

出于兴趣,我尝试将其与JUnit集成,结果发现这实际上非常简单(我将在以后进行介绍)。 到目前为止,结果是一个名为Oleaster的小型图书馆。

用Oleaster编写的测试如下所示:

import static com.mscharhag.oleaster.runner.StaticRunnerSupport.*;
...@RunWith(OleasterRunner.class)
public class AudioPlayerTest {private AudioPlayer player;{describe("AudioPlayer tests", () -> {beforeEach(() -> {player = new AudioPlayer();});it("should not play any track after initialization", () -> {assertFalse(player.isPlaying());});});}
}

与前面的示例相比,只有几处发生了变化。 在这里,测试类使用JUnit @RunWith注释进行注释。 这告诉JUnit在运行此测试类时使用Oleaster。 通过静态导入StaticRunnerSupport。*,可以直接访问静态Oleaster方法,例如describe()或it()。 还要注意,构造函数已由实例初始化程序替换,而Jasmine like matcher被标准JUnit断言替换。

与原始的茉莉花测试相比,实际上有一件事情并不那么出色。 实际上,在Java中,变量必须有效地最终确定才能在lambda表达式中使用。 这意味着以下代码段无法编译:

describe("AudioPlayer tests", () -> {AudioPlayer player;beforeEach(() -> {player = new AudioPlayer();});...
});

在beforeEach()lambda表达式内对玩家的赋值将不会编译(因为玩家实际上不是最终的)。 在Java中,我们必须在这种情况下使用实例字段(如上例所示)。

万一您担心要报告:Oleaster仅负责收集和运行测试用例。 整个报告仍由JUnit完成。 因此,Oleaster应该不会对使用JUnit报告的工具和库造成任何问题。

例如,以下屏幕截图显示了IntelliJ IDEA中Oleaster测试失败的结果:

oleaster-idea

如果您想知道Oleaster测试在实践中的外观,可以看看Oleaster的测试(这些测试是用Oleaster本身编写的)。 您可以在此处找到GitHub测试目录。

通过评论此帖子或创建GitHub问题,随时添加任何类型的反馈。

翻译自: https://www.javacodegeeks.com/2014/07/an-alternative-approach-of-writing-junit-tests-the-jasmine-way.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/362690.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决vue项目在ie浏览器中不显示的问题

安装 “babel-polyfill” npm install babel-polyfill --save-dev 或者 cnpm install babel-polyfill --save-dev在入口 main.js 文件引入:import babel-polyfill在 build 文件下的 webpack.base.conf.js 文件中修改代码: entry: {app: ["babel-p…

清空表单时出现问题

打开页面时报警告: 解决办法: (1)npm i default-passive-events -S (2)main.js中加入:import ‘default-passive-events’ 参考:https://www.jianshu.com/p/23850d4cade8 出现原…

如何在JSF中实现自定义密码强度指示器

使用JavaScript验证密码强度是一项常见任务。 在本文中,我将展示如何向基于JSF的Web应用程序添加密码强度指示器。 的 PrimeFaces中的密码组件已经具有密码强度的反馈指示符,但是它有两个主要缺点: 反馈指示器没有响应(固定宽度…

关于vue打包的问题

一、vue-cli2 二、vue-cli3 一、vue-cli2 错误提示: npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! hewelry1.0.0 build: node build/build.js npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the hewelry1.0.0 build script. npm ERR! This is prob…

html笔记(一)html4+css2.0、css基础和属性、盒模型

w3c 官网 这里是 html4 的内容 大标题小节一、关于HTML1. 基本语法2. HTML常用标签3. 相对路径和绝对路径二、css基础1. 表单元素2. 创建样式表3. css语法4. css选择器三、css的相关属性1. 列表 li 独有的属性list-style2. 边框属性border3. overflow4. 浮动 float 遇到的坑5.…

返回顶部小火箭

代码如下&#xff1a; <!DOCTYPE html> <html> <head lang"en"><meta charset"UTF-8"><title></title><style>body {width: 2000px;}.top{position: fixed;right:50px;bottom:100px;display: none;}</style&…

最佳5本Java性能调优书籍–精选,必读

为什么Java开发人员应该阅读有关性能调优的书&#xff1f; 当我很久以前第一次面对这个问题时&#xff0c;我以为以后会做&#xff0c;但是我很长一段时间都没有回过头来。 仅当我在用Java编写的任务关键型服务器端财务应用程序中遇到严重的性能和可伸缩性问题时&#xff0c;我…

html笔记(三)html5+css3(html5、css3、文字相关)

W3school在线教程 html5css3基本不兼容ie678。 大标题小节一、html51. html4 和 html5 的区别2. 标签语义化3. 智能表单的使用和规范二、css3选择器1. 属性选择器2. 结构性伪类选择器&#xff08;层级选择器/符&#xff09;3. UI状态性伪类选择器4. 相邻兄弟选择器5. 其他选择…

美登杯 E、小花梨的数组* 线段树

操作过程中标记传递 询问的时候再计算 #include<bits/stdc.h> using namespace std; //input by bxd #define rep(i,a,b) for(int i(a);i<(b);i) #define repp(i,a,b) for(int i(a);i>(b);--i) #define RI(n) scanf("%d",&(n)) #define RII(n,m) sc…

怎么得到scrollTop

我们学习一个事件 &#xff1a; 页面滚动效果 window.onscroll function() { 页面滚动语句 } 谷歌浏览器 和没有声明 DTD <DOCTYPE > &#xff1a; document.body.scrollTop; 火狐 和其他浏览器 document.documentElement.scrollTop; ie9 和 最新浏览器…

console.log打印没有效果

今天用谷歌调试的时候&#xff0c;遇到了一个很奇怪的现象&#xff0c;console.log() 完全不出效果&#xff0c;把它放到script下的第一行也没有用。然后借鉴了几个博主的。 直接改 https://blog.csdn.net/wujy_rrycbar2016/article/details/78341973 打开控制台 -> 改为 D…

CSS实战2

1. 鼠标样式 Cursor: pointer 鼠标变成小手 Cursor: default; 小白 Cursor : move; 移动 Cursor : text ; 文本输入 网页布局&#xff1a; 给一个盒子 &#xff1a; 宽度高度 背景 边框 位置 2.border-radius 圆角矩形 border-radius: 7px 7px 7p…

Linux Shell 常用命令与目录分区的学习总结

很早就想根据自己的学习规律和遗忘规律&#xff0c;自己总结一下Linux/Unix系统的Shell命令&#xff0c;一来便于自己时常查询之用&#xff0c;二来也分享于各位博友 Linux shell是系统的用户界面&#xff0c;即命令行。它提供了用户与内核进行交互式操作与控制的接口&#xff…

visual studio 应用场景

转载于:https://www.cnblogs.com/zhangbing12304/p/10894347.html

elementUI-添加自定义图标

elementui的小图标有限&#xff0c;跟UI给的不一样&#xff0c;这个时候咋办呢&#xff1f;百度走起。。。。参考了两篇博主分享的 自定义elementui中的图标 和 建立图标库&#xff0c;这里主要用到第一种 实际中&#xff1a; elementUI导航栏 具体代码&#xff1a; //自定…

echarts(一)下载引入,调色盘,[标题、图例组件、坐标轴]

一个简单的例子 1. 下载并引入 &#xff08;1&#xff09;npm install echarts --save &#xff08;2&#xff09;import echarts from echarts //main.js引入echarts 或者在组件中按需引入&#xff0c;查看按需引入的详细模块 <script>// 引入 ECharts 主模块var echa…

P3740 [HAOI2014]贴海报 离散化+线段树

题目描述 Bytetown城市要进行市长竞选&#xff0c;所有的选民可以畅所欲言地对竞选市长的候选人发表言论。为了统一管理&#xff0c;城市委员会为选民准备了一个张贴海报的electoral墙。 张贴规则如下&#xff1a; electoral墙是一个长度为N个单位的长方形&#xff0c;每个单位…

Dreamweaver Flash Photoshop网页设计综合应用 (智云科技) [iso] 1.86G​

全书共15章&#xff0c;主要包括网页制作基础、Dreamweaver CC网页制作、Photoshop CC网页图像设计、Flash CC网页动画设计以及综合案例实战5个部分。通过本书的学习&#xff0c;不仅能让读者学会三大软件的基本操作&#xff0c;而且本书中列举的实战案例&#xff0c;还可以让读…

如何使用示例从Java中的类路径加载资源

Java中的类路径不仅用于加载.class文件&#xff0c;而且还可以用于加载资源&#xff0c;例如属性文件&#xff0c;图像&#xff0c;图标&#xff0c;缩略图或任何二进制内容。 Java提供了API来将这些资源读取为InputStream或URL。 假设您在项目的config文件夹中有一个属性文件 …

Ext 3.0 +ASP.NET2.0 可视化开发介绍

Ext Designer 总算出来了&#xff01;&#xff01;&#xff01;基于Web的应用开发终于可以可视化开发了&#xff0c;而且可以几乎不敲1行代码。 准备工具&#xff1a; &#xff08;1&#xff09;Ext Designer 1.0.2 &#xff08;2&#xff09;Visual Studio 2005 第一步&#x…