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

编写junit 测试

最近,我为一个小型个人项目编写了很多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()函数调用使用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断言替换。

与原始的Jasmine测试相比,实际上有一件事情并不那么出色。 事实是,在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

编写junit 测试

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

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

相关文章

python4 什么时候_Python4要来了?快来看看Python之父怎么说

大家好,我是菜鸟哥,今天跟大家一起聊一下Python4的话题!从2020年的1月1号开始,Python官方正式的停止了对于Python2的维护。Python也正式的进入了Python3的时代。而随着时间的发展,关于Python4的发布也逐渐的成为了大家…

python类成员变量_Python 类变量和成员变量

Python 类变量和成员变量类与对象的方法我们已经讨论了类与对象的功能部分,现在我们来看一下它的数据部分。事实上,它们只是与类和对象的名称空间 绑定 的普通变量,即这些名称只在这些类与对象的前提下有效。有两种类型的 域 ——类的变量和对…

JDK 14 – JEP 361从预览中切换表达式

在我以前的文章中 ,我写了有关作为JDK 12的预览功能发布的开关表达式和相关增强功能的信息。随后,在JDK 13中提出了一些更改,例如使用yield关键字从switch块返回值并在预览中发布。 在即将于明年3月在GA上发布的即将发布的JDK 14版本中&…

输入一个正整数求所有素数因子_一个数如果恰好等于它的因子之和,这个数就称为完数。编写应用程序求1000以内所有的完数...

运行截图&#xff1a;代码import java.util.*;public class wanshu {public static void main(String args[]) {int sum 0,i,j,k,m 0;System.out.println(" 完数有&#xff1a;");for( j 2; j < 1000 ; j){for ( i 2 ; i < j; i){if( j%i 0) //此判…

安卓禁用硬件加速_Android硬件加速详解

从Android3.0(API Level 11)开始&#xff0c;支持硬件加速&#xff0c;可充分利用GPU的特性&#xff0c;使得界面渲染更加平滑。但是硬件加速自身并非完美&#xff0c;在某些Webview版本上&#xff0c;比如Android5初期的一些rom上的Webview版本是chrome37、38版本&#xff0c;…

mac svn工具_程序员或产品经理,这些Mac的效率工具一定不要错过

工欲善其事必先利其器!用好工具能很大的提高我们的工作效率&#xff0c;尤其是程序员和产品经理等。今天给大家介绍一些好用的工具随时记下闪现的灵感人的一天中大脑会产生大约6万个想法, 其中有不少优秀的 idea. 如果我们能学会捕捉哪怕是部分灵感, 也将会收获巨大. 因此工作中…

案例 github_github 项目搜索技巧-让你更高效精准地搜索项目

作者&#xff1a;Suwanbinwww.cnblogs.com/suwanbin/p/12113751.htmlgithub 搜索技巧参考自 B站 up 主 CodeSheep 的视频【如何高效地在网上找开源项目做&#xff01;在职程序员实际演示一波视频教程操作】&#xff0c;然后写着写着一好奇就去看文档了现在这篇博客相当于官方文…

使用Spring和JSR 303进行方法参数验证

Spring提供了一种使用JSR 303 bean验证来验证方法参数的简便方法。 在这篇文章中&#xff0c;我们将看到如何使用此功能。 设定 首先&#xff0c;我们需要通过创建MethodValidationPostProcessor bean添加对方法参数验证的支持&#xff1a; Configuration public class MyCon…

想要导航提示直接进入_北斗导航已开始提供全球服务,你的手机怎样连接北斗?...

如果你是新朋友&#xff0c;请点击上方的蓝色字 关注 “高科技爱好者”&#xff0c;保证不会让你失望的.自从北斗导航全球组网成功后&#xff0c;开始向全球提供导航服务&#xff0c;关于北斗导航的话题就没有断过&#xff0c;最常听到的两个话题&#xff1a;北斗收费吗&#x…

python3异步协程爬虫_Python实现基于协程的异步爬虫

Python实现基于协程的异步爬虫一、课程介绍1. 课程来源本课程核心部分来自《500 lines or less》项目&#xff0c;作者是来自 MongoDB 的工程师 A. Jesse Jiryu Davis 与 Python 之父 Guido van Rossum。项目代码使用 MIT 协议&#xff0c;项目文档使用 http://creativecommons…

python中变量的类型是动态的随时可以变化_python动态类型简介

1、a [1,2,3]其中a是变量名&#xff0c;[1,2,3]是对象&#xff0c;a通过一个指向[1,2,3]的指针引用了对象[1,2,3].2、每一个对象都有两个标准的头部信息&#xff0c;一个是标示这个对象的类型。另外一个是用来决定是不是可以回收这个对象。3、类型属于对象&#xff0c;而不属于…

jpa和hibernate_从JPA到Hibernate的旧版和增强型标识符生成器

jpa和hibernateJPA标识符生成器 JPA定义了以下标识符策略&#xff1a; 战略 描述 汽车 持久性提供程序选择基础数据库支持的最合适的标识符策略 身份 标识符由数据库IDENTITY列分配 序列 持久性提供程序使用数据库序列来生成标识符 表 持久性提供程序使用单独的数据库…

去掉前后空格_mysql批量去掉某个字段字符中的空格

mysql有什么办法批量去掉某个字段字符中的空格&#xff1f;不仅是字符串前后的空格&#xff0c;还包含字符串中间的空格&#xff0c;答案是 replace&#xff0c;使用mysql自带的 replace 函数&#xff0c;另外还有个 trim 函数。 &#xff08;1&#xff09;mysql replace 函数 …

python自己做个定时器_技术图文:如何利用 Python 做一个简单的定时器类?

原标题&#xff1a;技术图文&#xff1a;如何利用 Python 做一个简单的定时器类&#xff1f;背景今天在B站上看有关 Python 最火的一个教学视频 -- “零基础入门学习 Python”&#xff0c;这也是我们 Python基础刻意练习活动 的推荐视频教程。python视频在学习魔法方法的时候&a…

成为Java流大师–第6部分:使用流创建新的数据库应用程序

您是否曾经想开发数据库应用程序的“快速”版本&#xff1f; 在此动手实验文章中&#xff0c;您将学习一种真正简单而直接的方法。 整个Java域模型将自动为您生成。 您只需连接到现有数据库&#xff0c;然后开始使用Java流进行开发。 例如&#xff0c;您将能够在几分钟内为您现…

快速排序 挖坑_由浅入深玩转快速排序算法

由浅入深玩转快速排序算法快速排序可以说是最快的通用排序算法&#xff0c;它甚至被誉为20世纪科学和工程领域的十大算法之一。在众多排序算法中其无论是时间复杂度还是空间复杂度都颇具优势。作为开发工程师&#xff0c;我们很有必要了解它的思想。接下来将由在下为大家一步步…

代码拾取图片某一点的颜色_RPG游戏开发日志7:道具拾取与存放

本项目同步上传于github和coding上&#xff0c;国内读者可以通过在coding下载项目。也欢迎你加入我的UE4学习交流QQ群&#xff1a;872537977。如果你喜欢我写的文章&#xff0c;也希望你点赞、收藏、转发。谢谢&#xff01;如果你喜欢我写的文章&#xff0c;也希望你点赞、收藏…

使用sstableloader恢复Cassandra Priam备份

之前&#xff0c;我曾写过关于设置Cassandra和Priam进行备份和集群管理的文章。 但是&#xff0c;我在此处提供的用于备份还原的示例并不适用于所有情况&#xff0c;例如&#xff0c;它可能不适用于完全独立的群集。 或者在部分还原到一个表而不是整个数据库的情况下。 在这种…

abp vue如何配置服务地址_DHCP服务如何配置才能尽量减少被攻击的可能

DHCP Snooping是啥&#xff1f;DHCP Snooping是DHCP的一种安全特性&#xff0c;用来保证DHCP客户端能够正确的从DHCP服务器获取IP地址&#xff0c;防止网络中针对DHCP的攻击。DHCP Snooping是如何防止DHCP攻击的呢&#xff1f;DHCP&#xff0c;动态主机配置协议&#xff0c;在I…

通达信缠论买卖点公式_通达信缠论多空主图指标公式

1.高位无量就拿&#xff0c;就算拿错了也要拿着。高位就是说股价处于或者接近历史的最高位。高位无量横盘&#xff0c;是非常典型的上涨中继形态之一&#xff0c;高位的窄幅箱型振荡。2.高位放量出现就要跑,哪怕是跑错也要跑。股价在已经过了一段时间比较大的涨幅后&#xff0c…