junit测试起名字规则_如何在JUnit 5中替换规则

junit测试起名字规则

最近发布的JUnit 5(又名JUnit Lambda) alpha发行版引起了我的兴趣,在浏览文档时,我注意到规则以及运行程序和类规则都消失了。 根据文档,这些部分竞争的概念已被单个一致的扩展模型取代。

多年来, Frank和我写了一些规则来帮助执行重复性任务,例如测试SWT UI , 忽略某些环境中的测试 , 注册(测试)OSGi服务 , 在单独的线程中运行测试等等。

因此,我对将现有规则转换为新概念以使它们可以在JUnit 5上本地运行特别感兴趣,为了探索扩展的功能,我选择了两个特性完全不同的规则,并尝试将其迁移到JUnit 5 。

这些实验的重点是查看规则和扩展之间的概念已发生了变化。 因此,我选择重写JUnit 4意味着不考虑向后兼容性。

如果您有兴趣从JUnit 4迁移到5或探索在JUnit 5中运行现有规则的可能性,则可能需要参加各自的讨论。

第一个候选对象是ConditionalIgnoreRule ,它与@ConditionalIgnore批注一起使用。 该规则评估需要用注释指定的条件,并据此确定是否执行测试。

另一个候选者是内置的TemporaryFolder规则 。 顾名思义,它允许创建在测试完成时删除的文件和文件夹。

因此,它在测试执行之前和之后挂接,以创建一个根目录以在其中存储文件和文件夹并清理该目录。 另外,它提供了实用程序方法来在根目录中创建文件和文件夹。

扩展说明

在详细介绍向扩展的迁移规则之前,让我们简要了解一下新概念。

junit5扩展点类型层次结构

测试执行遵循一定的生命周期。 可以延长生命周期的每个阶段都由一个接口表示。 扩展可以实现某些阶段的兴趣,因为它们实现了相应的接口。

使用ExtendWith批注,测试方法或类可以表示它在运行时需要特定的扩展。 所有扩展都有一个公共的超级接口: ExtensionPointExtensionPoint的类型层次结构列出了扩展当前可以挂接到的所有位置。

例如,下面的代码应用了一个虚构的MockitoExtension来注入模拟对象:

@ExtendWith(MockitoExtension.class)
class MockTest {@MockFoo fooMock; // initialized by extension with mock( Foo.class )
}

MockitoExtension将提供一个默认的构造函数,以便它可以在运行时实例化并实现必要的扩展接口,以便能够将@Mock注入到所有@Mock注释的字段中。

条件忽略

规则的重复模式是提供带有注释的串联服务,该注释用于标记和/或配置希望使用该服务的测试方法。 在这里,ConditionalIgnoreRule检查其运行的所有测试方法,并寻找ConditinalIgnore批注。 如果找到这样的注释,则评估其条件,如果满足,则忽略测试。

这是ConditionalIgnoreRule实际运行的样子:

@Rule
public ConditionalIgnoreRule rule = new ConditionalIgnoreRule();@Test
@ConditionalIgnore( condition = IsWindowsPlatform.class )
public void testSomethingPlatformSpecific() {// ...
}

现在,让我们看一下代码在JUnit 5中的外观:

@Test
@DisabledWhen( IsWindowsPlatform.class )
void testSomethingPlatformSpecific() {// ...
}

首先,您会注意到注释已更改其名称。 为了匹配使用术语Disabled而不是忽略的JUnit 5约定,该扩展还将其名称更改为DisabledWhen

尽管DisabledWhen注释是由DisabledWhenExtension驱动的,但是没有任何东西表明需要扩展。 其原因被称为元注释,并且在查看DisabledWhen的声明方式时可以最好地说明它们:

@Retention(RetentionPolicy.RUNTIME)
@ExtendWith(DisabledWhenExtension.class)
public @interface DisabledWhen {Class<? extends DisabledWhenCondition> value();
}

注释(元)带有处理它的扩展名注释。 在运行时,JUnit 5测试执行器负责其余的工作。 如果遇到带注释的测试方法,并且该注释又由ExtendWith元注释,则实例化各个扩展并将其包含在生命周期中。

真的很整洁吗? 在不指定相应规则的情况下注释测试方法时,此技巧还可以避免疏忽。

在幕后, DisabledWhenExtension实现了TestExexutionCondition接口。 对于每个测试方法,都将调用其唯一的evaluate()方法,并且必须返回一个ConditionEvaluationResult ,该ConditionEvaluationResult确定是否应该执行测试。

其余代码与以前基本相同。 查找并找到DisabledWhen注释时,将创建指定条件类的实例,并询问是否应执行测试。 如果执行被拒绝,则返回一个禁用的ConditionEvaluationResult ,并且框架将相应地执行操作。

临时文件夹

在将TemporaryFolder规则转换为异常之前,让我们看一下该规则的组成。 首先,该规则将在测试设置和拆卸期间进行设置并清理一个临时文件夹。 但是,它还为测试提供了访问在该根文件夹内创建(临时)文件和文件夹的方法的权限。

迁移到扩展后,不同的职责变得更加明显。 以下示例显示了如何使用它:

@ExtendWith(TemporaryFolderExtension.class)
class InputOutputTestprivate TemporaryFolder tempFolder;@Testvoid testThatUsesTemporaryFolder() {F‌ile f‌ile = tempFolder.newF‌ile();// ...}
}

TemporaryFolderExtension挂接到测试执行生命周期中,以提供和清除临时文件夹,并为所有TemporaryFolder字段提供此类实例。 而TemporaryFolder允许访问在根文件夹中创建文件和文件夹的方法。

为了注入TemporaryFolder ,该扩展实现了InstancePostProcessor接口。 创建测试实例后立即调用其postProcessTestInstance方法。 在该方法中,它可以通过TestExtensionContext参数访问测试实例,并且可以将TemporaryFolder注入所有匹配的字段中。

对于一个类声明多个TemporaryFolder字段的极少数情况,每个字段都被分配一个新实例,并且每个实例都有其自己的根文件夹。

在此过程中创建的所有注入的TemporaryFolder实例都保存在一个集合中,以便稍后进行清理时可以对其进行访问。

要在执行测试后进行清理,需要实现另一个扩展接口: AfterEachExtensionPoint 。 每次测试完成后,将调用其唯一的afterEach方法。 并且此处的TemporaryFolderExtension实现清除了所有已知的TemporaryFolder实例。

现在我们可以与TemporaryFolder规则的功能相提并论,现在还可以支持新功能:方法级依赖注入。
在JUnit 5中,现在允许方法具有参数。
这意味着我们的扩展程序不仅应该能够注入字段,而且还应该能够注入TemporaryFolder类型的方法参数。 希望创建临时文件的测试可以请求注入TemporaryFolder如以下示例所示:

class InputOutputTest {@Test@ExtendWith(TemporaryFolderExtension.class)void testThatUsesTemporaryFolder( TemporaryFolder tempFolder ) {F‌ile f‌ile = tempFolder.newF‌ile();// ...}
}

通过实现MethodParameterResolver接口,扩展可以参与解析方法参数。 对于测试方法的每个参数,都会调用扩展的supports()方法来确定它是否可以为给定参数提供值。 对于TemporaryFolderExtension ,实现将检查参数类型是否为TemporaryFolder并在这种情况下返回true 。 如果需要更广泛的上下文,则当前方法调用上下文和扩展上下文还提供了supports()方法。

现在,该扩展程序决定支持某个参数,它的resolve()方法必须提供一个匹配的实例。 同样,提供了周围的环境。 TemporaryFolderExtension仅返回一个唯一的TemporaryFolder实例,该实例知道(临时)根文件夹并提供在其中创建文件和子文件夹的方法。

但是请注意,声明无法解析的参数被视为错误。 因此,如果遇到没有匹配解析器的参数,则会引发异常。

在扩展中存储状态

您可能已经注意到, TemporaryFolderExtension保持其状态(即,它已创建的临时文件夹的列表),当前是一个简单字段。 尽管测试表明这确实可行,但是文档中没有地方指出在调用不同扩展名时都使用同一实例。 因此,如果JUnit 5此时更改其行为,则在这些调用期间状态可能会丢失。

好消息是,JUnit 5提供了一种维护称为Store的扩展状态的方法。 正如文档所述,它们为扩展提供了保存和检索数据的方法

该API与简化Map的API类似,并且允许存储键值对,获取与给定键关联的值以及删除给定键。 键和值都可以是任意对象。 可以通过将TestExtensionContext作为参数传递给每个扩展方法(例如beforeEachafterEach )来到达存储。每个TestExtensionContext实例都封装了正在执行当前测试的上下文

例如,在beforeEach ,值将存储在扩展上下文中,如下所示:

@Override
public void beforeEach( TestExtensionContext context ) {context.getStore().put( KEY, ... );
}

以后可以像这样检索:

@Override
public void afterEach( TestExtensionContext context ) {Store store = context.getStore();Object value = store.get( KEY );// use value...
}

为了避免可能发生的名称冲突,可以为某些命名空间创建存储。 上面使用的context.getStore()方法获取默认名称空间的存储。 要获取特定命名空间的商店,请使用

context.getStore( Namespace.of( MY, NAME, SPACE );

名称空间是通过对象数组{ MY, NAME, SPACE }在此示例中。

返还TemporaryFolderExtension以使用Store的练习留给读者。

运行代码

  • 可以在以下GitHub存储库中找到此处讨论的两个扩展的扩展实现: https : //github.com/rherrmann/junit5-experiments

该项目设置为在安装了Maven支持的Eclipse中使用。 但是在具有Maven支持的其他IDE中编译和运行代码并不难。

很自然,在这种早期状态下,尚不支持直接在Eclipse中运行JUnit 5测试。 因此,要运行所有测试,您可能需要使用“使用ConsoleRunner运行所有测试”启动配置。 如果遇到麻烦,请参考我以前关于JUnit 5的文章中的“ 使用JUnit 5运行测试”部分,以获得更多提示或发表评论。

总结如何在JUnit 5中替换规则

在这个小小的实验过程中,我给人的印象是,扩展是JUnit 4中规则和朋友的不错且完全的替代品。最后,使用新方法很有趣,并且比现有功能更简洁。

如果您发现用扩展尚无法完成的用例,我相信如果让他们知道 JUnit 5团队将不胜感激。

但是请注意,截至撰写本文时,扩展程序仍在进行中 。 该API被标记为实验性的,如有更改,恕不另行通知。 因此,现在实际迁移JUnit 4帮助程序可能还为时过早-除非您不介意将代码调整为可能更改的API。

如果JUnit 5扩展引起了您的兴趣,您可能还需要继续阅读文档的相应章节 。

翻译自: https://www.javacodegeeks.com/2016/04/replace-rules-junit-5.html

junit测试起名字规则

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

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

相关文章

android照片编辑软件,照片编辑免费软件下载-照片编辑软件app下载 v7.45最新版_5577安卓网...

照片编辑免费软件app下载&#xff0c;提供给你全新的图片处理工具&#xff0c;这是软件包含了丰富的功能内容&#xff0c;软件一键即可轻松对各种照片組合、编辑和拼貼&#xff0c;那么有需要图片处理的用户下载该app使用吧&#xff01;【软件特色】【 拼图编辑&#xff1a;强大…

扩展 junit 框架_JUnit 5 –扩展模型

扩展 junit 框架我们已经对Java最普遍的测试框架的下一个版本了解很多。 现在&#xff0c;让我们看一下JUnit 5扩展模型&#xff0c;该模型将允许库和框架将自己的实现添加到JUnit中。 总览 建立 基本 建筑 扩展模型 条件 注射 … 在新兴的《 JUnit 5用户指南》中可以找…

【斐波拉切数列第N项】

#include<iostream> using namespace std;int main() {int f[100];f[0] 0, f[1] 1;int n;cin >> n;for (int i 2; i < n; i){f[i] f[i - 1] f[i - 2];}cout <<f[n] << endl;return 0; }

python怎么下载安装mac_Mac下内置python2.7如何安装模块?

目前电脑里内置的版本是python2.7 用easy_install下载了几个模块&#xff0c;再输入pip list&#xff0c;得到&#xff1a; beautifulsoup4 (4.5.1) easygui (0.98.0) pip (8.1.2) setuptools (20.10.1) vboxapi (1.0) 可以确定我想要的bs4已经下载成功。然后我再输入python se…

jooq_SpringBoot:与JOOQ合作

jooq在上一篇文章SpringBoot&#xff1a;与MyBatis一起工作中&#xff0c;我们学习了如何使用SpringBoot MyBatis Starter快速启动并运行Spring和MyBatis。 在本文中&#xff0c;我们将学习如何使用SpringBoot JOOQ Starter。 JOOQ&#xff08;面向Java对象的查询&#xff09;…

【WebRTC---入门篇】(十二)WebRTC传输协议

浏览器协议栈(左图传统HTTP 右图WebRTC) RTP/SRTP RTP是未加密的数据,SRTP是加密后的数据。 RTP协议

android4.0支持m3u8格式,【报Bug】安卓下无法播放M3U8格式音频,报错

详细问题描述(DCloud产品不会有明显的bug&#xff0c;所以你遇到的问题大都是在特定环境下才能重现的问题&#xff0c;请仔细描述你的环境和重现方式&#xff0c;否则DCloud很难排查解决你的问题)[内容]安卓下小程序音频播放器播放&#xff2d;3&#xff35;8格式文件报错重现步…

springcloud官方文档_通俗易懂!Spring Cloud简介:官方文档翻译版

什么是微服务&#xff1f;"微服务架构是一种架构模式&#xff0c;它提倡将单一应用程序划分成一组小的服务&#xff0c;服务之间相互协调、互相配合&#xff0c;为用户提供最终价值。每个服务运行在其独立的进程中&#xff0c;服务和服务之间采用轻量级的通信机制相互沟通…

【RTMP协议分析与抓包实测】

传输协议 RTMP基本通讯 RTMP基于TCP之上传输 TCP三次握手,相关文章链接&#xff0c;TCP三次握手流程 进行握手 c- --> s 发送c0c1 c ---> s 发送c2 s ---> c 发送s0s1s2 建立RTMP连接 真实建立连接的场景 c- --> s RTMP发送connect建立连接 s ---> c 协商(滑动…

autowired_@Autowired所有的东西!

autowired最近&#xff0c;我写了Autowired注释 &#xff0c;它使我们可以编写更少的代码&#xff0c;从而使我们的生活更轻松 。 但是&#xff0c;使用它通常会使您的设计更加复杂。 尤其是当我们谈论在类的属性上使用它时。 它更容易违反 单一责任原则 。 这样可以更容易地注…

android message 代码,Android Handler移除Message详解及实例代码

Android Handler移除Message详解问题&#xff1a;1.removeMessage(what)函数是否只能移除对应what值的Message&#xff1f;2.对于Delayed发送的Message&#xff0c;能否提前remove&#xff1f;代码测试&#xff1a;package javine.k.testhandler;import android.app.Activity;i…

python中如何调用或修改元组中的元素_python 元组的使用方法

元组——tuple 列表非常适合用于存储在程序运行期间可能变化的数据集。 列表是可以修改的&#xff0c;但元组是不可修改的 Python将不能修改的值称为不可变的&#xff0c;而不可变的列表被称为元组 1. 元组的创建和删除 &#xff08;1&#xff09;使用赋值运算符直接创建元组 语…

【WebRTC---入门篇】(十三)WebRTC音视频数据采集

音视频采集API false表示不采集,true表示采集 WebRTC API适配 获取音视频设备的访问权限 通过 return navigator.mediaDevices.enumerateDevices();/*返回一个promise,为了获取音视频的权限*/ 视频约束

android按钮点击toast,关于button点击事件中setOnClick等元素的解读以及方法?以及toast的位置以及作用?...

此文末参考链接&#xff1a;此段代码的教程以及使用接口的方式、switch语句的教程链接为链接1.汇总里说的有更多的实现方法&#xff0c;为链接2。文中链接为视觉统一&#xff0c;链接均于文末&#xff0c;以上为方便文中跳转&#xff0c;加了文中的跳转链接。以下代码为我学习b…

java用什么编译器_Java用Java编译

java用什么编译器在上一篇文章中&#xff0c;我写了关于如何在运行时生成代理的内容&#xff0c;我们已经了解到生成Java源代码的程度。 但是&#xff0c;要使用该类&#xff0c;必须对其进行编译&#xff0c;并将生成的字节码加载到内存中。 那是“编译”时间。 幸运的是&…

app登录界面背景 css_计算机毕业设计中Java web实现简登录页面(MyBatis+jsp+servlet+html+css+javascript)...

点击上方“蓝字”&#xff0c;关注我们.本文利用MyBatisjspservlethtmlcssjavascript实现了一个简单的登录页面。对用户输入的用户名和密码就行校验&#xff0c;校验通过则登录成功&#xff0c;密码和用户信息保存在mysql表中&#xff0c;通过MyBatis访问(MyBatis相关知识可参考…

android strm,Android 关于so文件的随记

1.背景&#xff1a;项目中要集成商汤的活体检测sdk&#xff0c;2.遇到的问题&#xff1a;商汤提供的demo 可以正常运行&#xff0c;但是将sdk集成至项目中时一直报错&#xff0c;但是商汤侧却没办法提供具体的报错原因3.解决问题&#xff1a;反编译商汤的源码发现&#xff0c;报…

工业互联网二级节点建设_建设者还是二传手?

工业互联网二级节点建设不用说&#xff0c;每个对象都需要先创建才能使用。 无论我们是在谈论域&#xff0c;框架&#xff0c;库还是任何其他类型的类&#xff0c;都没有关系。 当您的代码是面向对象的时&#xff0c;这些类仅是对象的定义。 创建对象之前&#xff0c;不能使用它…

android 指针是什么意思,Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析(3)...

提供引用计数器的类RefBase我们就暂时介绍到这里&#xff0c;后面我们再结合智能指针类一起分析&#xff0c;现在先来看看强指针类和弱指针类的定义。强指针类的定义我们在前面介绍轻量级指针的时候已经见到了&#xff0c;就是sp类了&#xff0c;这里就不再把它的代码列出来了。…