使用JUnit 5进行更清洁的参数化测试

参数化单元测试的总体思路是对不同的数据运行相同的测试方法。 在JUnit 4中创建参数化测试远非完美。 现有体系结构存在许多问题:将参数定义为类字段,并且需要使用构造函数来创建它们,不能将参数化和非参数化测试混合在一个测试类中,并且内置数据源非常有限。 幸运的是,所有这些都在JUnit 5中得到了改进!

注意:作为JUnit 4参数化测试的替代方法,您可以使用JUnitParams库来解决我提到的许多问题(请在此处查看有关JUnitParams的博客文章: http : //blog.codeleak.pl/2013/12/parametrized-junit- tests-with.html )。

如何开始?

要开始在Junit 5中进行参数化测试,您需要向项目添加必需的依赖项:向项目添加org.junit.jupiter:junit-jupiter-params:${junitJupiterVersion}依赖项以使用参数化测试,参数提供程序和转换器。

SUT –被测系统

我创建的所有示例都在测试FizzBu​​zz类:

public class FizzBuzz {private static final int THREE = 3;private static final int FIVE = 5;public String calculate(int number) {if (isDivisibleBy(number, THREE) && isDivisibleBy(number, FIVE)) {return "FizzBuzz";}if (isDivisibleBy(number, THREE)) {return "Fizz";}if (isDivisibleBy(number, FIVE)) {return "Buzz";}return String.valueOf(number);}private static boolean isDivisibleBy(int dividend, int divisor) {return dividend % divisor == 0;}
}

尽管FizzBu​​zz非常简单,但是它也可以用于演示更高级的单元测试技术,例如实现参数化测试。

我在JUnit 5中的第一个参数化测试

要在JUnit 5中创建参数化测试,请使用@org.junit.jupiter.params.ParameterizedTest (而不是@Test )注释测试方法,并提供参数来源:

@ParameterizedTest(name = "{index} => calculate({0})")
@ValueSource(ints = {1, 2, 4, 7, 11, 13, 14})
public void returnsNumberForNumberNotDivisibleByThreeAndFive(int number, TestInfo testInfo) {assertThat(fizzBuzz.calculate(number)).isEqualTo("" + number);
}

注释具有可选的name属性,用于自定义调用显示名称。 可用的模板变量:{index}->当前调用索引(从1开始),{arguments}->完整的,逗号分隔的参数列表,{0},{1},…->一个单独的参数。

在此示例中, @org.junit.jupiter.params.provider.ValueSource提供对整数文字值数组的访问。 必须在此批注中提供一种输入类型(字符串,实例,长整型或双精度型)。

我还提供了由org.junit.jupiter.api.extension.ParameterResolver解析的其他参数。 请注意,由参数源解析的方法参数需要在参数列表中排在首位。

更多论点来源

@MethodSource

@ParameterizedTest(name = "{index} => calculate({0})")
@MethodSource(names = {"divisibleByThree", "divisibleByThreeButNotFive"})
void returnFizzForNumberDivisibleByThree(int number) {assertThat(fizzBuzz.calculate(number)).isEqualTo("Fizz");
}

@org.junit.jupiter.params.provider.MethodSource引用返回自变量源的方法(1个或更多)。 在此示例中,有两种方法:

private static Stream<Integer> divisibleByThree() {int[] ints = new int[]{18, 21};return Stream.of(3, 6, 9, 12);
}// The returned array will be converted to a Stream
private static String[] divisibleByThreeButNotFive() {return new String[]{"18", "21"};
}

提供参数的方法必须是静态的,不能包含任何参数,并且必须返回Stream,Iterable,Iterator或数组。 您可能会注意到, divisibleByThreeButNotFive()方法返回一个字符串数组。 由于内置了隐式参数转换器,因此可以很好地工作。 当参数源是CSV时(这在下面有更多说明),这确实很有用。 此外,可以使用自定义参数转换器来转换参数。

要解析多个参数,方法源将返回org.junit.jupiter.params.provider.Arguments实例流( org.junit.jupiter.params.provider.ObjectArrayArguments ):

@ParameterizedTest(name = "{index} => calculate({0}) should return {1}")
@MethodSource(names = {"fizzBuzz"})
void fizzBuzz(int number, String expectedResult) {assertThat(fizzBuzz.calculate(number)).isEqualTo(expectedResult);
}private static Stream<Arguments> fizzBuzz() {return Stream.of(ObjectArrayArguments.create(1, "1"),ObjectArrayArguments.create(2, "2"),ObjectArrayArguments.create(3, "Fizz"),ObjectArrayArguments.create(4, "4"),ObjectArrayArguments.create(5, "Buzz"),ObjectArrayArguments.create(6, "Fizz"),ObjectArrayArguments.create(7, "7"),ObjectArrayArguments.create(8, "8"),ObjectArrayArguments.create(9, "Fizz"),ObjectArrayArguments.create(15, "FizzBuzz"));
}

@CsvFileSource

提供参数源的另一种非常有趣的方法是org.junit.jupiter.params.provider.CsvFileSource ,它从类路径中的多个CSV文件之一中提供参数:

@ParameterizedTest(name = "{index} => calculate({0}) should return {1}")
@CsvFileSource(resources = {"/fizzbuzz/fizzbuzz_1.csv", "/fizzbuzz/fizzbuzz_2.csv"}, delimiter = ';')
void fizzBuzzCsv(int number, String expectedResult) {assertThat(fizzBuzz.calculate(number)).isEqualTo(expectedResult);
}

其他论点

  • @EnumSource提供了使用Enum常量的便捷方法。
  • @CsvSource允许您将参数列表表示为以逗号分隔的值
  • @ArgumentsSource可用于指定自定义,可重用的参数提供程序。

享受JUnit 5中的参数化测试!

资源资源

可以在GitHub上找到本文中介绍的所有示例: https : //github.com/kolorobot/unit-testing-demo

查看官方的JUnit 5文档以了解更多信息: http : //junit.org/junit5/docs/current/user-guide/#writing-tests-parameterized-tests

翻译自: https://www.javacodegeeks.com/2017/06/cleaner-parameterized-tests-junit-5.html

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

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

相关文章

问题 1045: [编程入门]自定义函数之整数处理

题目描述输入10个整数&#xff0c;将其中最小的数与第一个数对换&#xff0c;把最大的数与最后一个数对换。写三个函数&#xff1b; ①输入10个数&#xff1b;②进行处理&#xff1b;③输出10个数。输入10个整数输出整理后的十个数&#xff0c;每个数后跟一个空格&#xff08;注…

我曾经是怎么做面试官的

阅读提示 更新于2019年2月3日&#xff1a;本文过于注重技巧&#xff0c;很多内容笔者已不再使用。这是成长的必经过程&#xff0c;正如独孤求败的剑术精进之路&#xff0c;先注重技巧&#xff0c;再内化&#xff0c;变得不拘泥于形式。 纵然本文内容已不完全与笔者真正的面试风…

大数据摄取:Flume,Kafka和NiFi

初赛 在构建大数据管道时&#xff0c;我们需要考虑如何吸收出现在通常是Hadoop生态系统大门口的数据量&#xff0c;多样性和速度。 在决定采用哪种工具来满足我们的要求时&#xff0c;诸如可伸缩性&#xff0c;可靠性&#xff0c;适应性&#xff0c;开发时间成本等方面的初步考…

__repr__

class Item: def __init__ (self, name, price): self.name name self.price price # 创建一个Item对象&#xff0c;将之赋给im变量 im Item(鼠标, 29.8) # 打印im所引用的Item对象 print(im) 先看下面程序&#xff1a; 上面程序创建了一个 Item 对象&#xff0c;然后使用 p…

__getattribute__

在类 里面,其实并没有方法这个东西,所有的东西都保存在属性里面,所谓的调用方法其实是类里面的一个同名属性指向了一个函数(方法),返回的是函数的引用,再用 函数() 这种方式就可以调用它 在调用实例的方法的时候,实际上给对象传过去的只是一个字符串而已, 比如 t Test()…

使用精确的Java方法参数

了解如何在Java应用程序中选择正确的方法参数类型并获得更健壮和更短的代码。 我们Java开发人员通常有一个使用方法参数的坏习惯&#xff0c;即不考虑实际需要什么&#xff0c;而只是选择我们习惯的&#xff0c;可用的或首先想到的东西。 考虑以下代表性示例&#xff1a; pri…

Android external storage

File sdCard Environment.getExternalStorageDirectory(); File directory_pictures new File(sdCard, "Pictures"); Log.i(TAG,"directory_pictures"directory_pictures); 存储在external storage 这类文件不应该存在SD卡的根目录下&#xff0c;而应该存…

EnjoyingSoft之Mule ESB开发教程第六篇:Data Transform - 数据转换

目录 1. 数据转换概念2. 数据智能感知 - DataSense3. 简单数据转换组件3.1 Object to JSON3.2 JSON to XML3.3 JSON to Object3.4 XML to JSON4. 企业版的DataWeave Transformer(可视化高级数据转换器)5. 社区版的InfoMapper(自研的可视化数据转换器)本篇主要介绍在Mule ESB中使…

反射和内省_单例设计模式–内省和最佳实践

反射和内省定义&#xff1a; Singleton是“ 四人帮”设计模式的一部分&#xff0c;它属于创新设计模式。 在本文中&#xff0c;我们将更深入地研究Singleton模式的用法。 就建模而言&#xff0c;它是最简单的设计模式之一&#xff0c;但另一方面&#xff0c;就使用的复杂性而言…

福利预告,跳一跳助手即将发布,您不知道还有这些...

福利预告&#xff0c;跳一跳助手即将来临 一周后&#xff0c;即2月9号正式发布 跳一跳助手&#xff0c;免费免费免费提供&#xff01; 透露一下 跳一跳助手的界面是这样滴&#xff1a; 这工具有啥用&#xff1f; 举个栗子&#xff1a; 花城君用该工具&#xff0c;不小心就玩到…

Redis Client Lettuce 5 GA发布

经过13个月的开发阶段和208张已解决的故障单&#xff0c;我很高兴宣布Lettuce 5.0全面上市。 这是一个主要发行版&#xff0c;带有一些重大更改&#xff0c;新的有趣功能以及Java 9兼容性。 从Maven Central获取发布 <dependency><groupId>io.lettuce</groupI…

NOIP模拟测试14「旋转子段·走格子·柱状图」

旋转子段 连60分都没想&#xff0c;考试一直肝t3&#xff0c;t2&#xff0c;没想到t1最简单 我一直以为t1很难&#xff0c;看了题解发现也就那样 题解 性质1 一个包含a[i]旋转区间值域范围最多为min(a[i],i)----max(a[i],i) 感性理解 举个例子,例如3 7 1 4 5 6 2 这个子段包含a…

检测域名是否到期

如果你想做一个网站&#xff0c;首先需要购买一个域名&#xff0c;与其说是购买不如说是租用&#xff0c;因为你要想使用这个域名&#xff0c;每年都需要缴纳一笔费用。既然是租用&#xff0c;所以就有期限&#xff0c;在到期前没有续费&#xff0c;则该域名会被收回&#xff0…

jax-ws cxf_走向REST:在Spring和JAX-RS(Apache CXF)中嵌入Jetty

jax-ws cxf对于服务器核心Java开发人员来说&#xff0c;向世界“展示”的唯一方法是使用API​​。 今天的帖子都是关于JAX-RS的 &#xff1a;使用Java编写和公开RESTful服务。 但是&#xff0c;我们不会使用涉及应用程序服务器&#xff0c;WAR打包以及诸如此类的传统的重量级方…

问题 1046: [编程入门]自定义函数之数字后移

题目描述有n个整数&#xff0c;使前面各数顺序向后移m个位置&#xff0c;最后m个数变成前面m个数。写一函数&#xff1a;实现以上功能&#xff0c;在主函数中输入n个数和输出调整后的n个数。输入输入数据的个数n n个整数 移动的位置m输出移动后的n个数样例输入10 1 2 3 4 5 6 7…

Reliable Multicast Programming(PGM)协议

Reliable Multicast Programming (PGM)实际通用可靠多播协议&#xff0c;在某种程度上保证多播的可靠性。是IP上层协议&#xff0c;和TCP还有UDP同级&#xff0c;工作在传输层。 在组播传输视频项目中&#xff0c;发现在网络较差的时候&#xff0c;组播传输视频性能下降迅猛&am…

P1488 肥猫的游戏

P1488 肥猫的游戏https://www.luogu.org/problem/P1488 博弈论一个三角形&#xff0c;只有三种情况&#xff1a;1邻接&#xff0c;2邻接&#xff0c;3邻接主要是2邻接的情况比较麻烦边<0,n-1>需要特判一下 #include <iostream> #include <cstdio> #include &…

使用OAuth2令牌的安全REST服务

1.简介 在本教程中&#xff0c;我们将介绍如何将Spring Security与OAuth结合使用以保护REST服务。 在演示应用程序中&#xff0c;可以使用路径模式&#xff08; / api / ** &#xff09;访问服务器上受保护的REST资源&#xff0c;以便基于该路径的请求URL映射到不同的控制器方法…

java 内联调用深度_Java中内联虚拟方法调用的性能

java 内联调用深度总览 动态编译的好处之一是它能够支持在虚拟方法代码上的广泛方法内联。 内联代码可提高性能时&#xff0c;代码仍必须检查类型&#xff08;以防由于优化而更改了类型&#xff09;或在多个可能的实现之间进行选择。 这导致了问题。 通过接口调用的方法的多个…

组件切换方式(Vue.js)

这里&#xff0c;我用一个注册登录两组件的切换实例来演示&#xff1a; 切换方式一 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8" /><title>独秀不爱秀</title> </head><body><div …