junit 预期错误_谨慎使用JUnit的预期异常

junit 预期错误

有时,当我们收到对jOOQ或其他库的拉取请求时,人们会将单元测试中的代码更改为更“惯用的JUnit”。 特别是,这意味着他们倾向于更改此代码(公认的不是那么漂亮的代码):

@Test
public void testValueOfIntInvalid() {try {ubyte((UByte.MIN_VALUE) - 1);fail();}catch (NumberFormatException e) {}try {ubyte((UByte.MAX_VALUE) + 1);fail();}catch (NumberFormatException e) {}
}

…成为“更好”和“更清洁”的版本:

@Test(expected = NumberFormatException.class)
public void testValueOfShortInvalidCase1() {ubyte((short) ((UByte.MIN_VALUE) - 1));
}@Test(expected = NumberFormatException.class)
public void testValueOfShortInvalidCase2() {ubyte((short) ((UByte.MAX_VALUE) + 1));
}

我们获得了什么?

没有!

当然,我们已经必须使用@Test批注,因此我们不妨使用其expected的属性吧? 我声称这是完全错误的。 有两个原因。 当我说“两个”时,我的意思是“四个”:

1.在代码行数方面,我们并没有真正获得任何好处

比较语义上有趣的位:

// This:
try {ubyte((UByte.MIN_VALUE) - 1);fail("Reason for failing");
}
catch (NumberFormatException e) {}// Vs this:
@Test(expected = NumberFormatException.class)
public void reasonForFailing() {ubyte((short) ((UByte.MAX_VALUE) + 1));
}

给定或采用空格格式,基本语义信息量完全相同:

  1. 该方法正在测试中的ubyte() 。 这不会改变
  2. 我们要传递给失败报告的消息(以字符串或方法名称的形式)
  3. 异常类型和预期的事实

因此,即使从样式角度来看,这也不是真正有意义的更改。

2.无论如何我们都必须将其重构

在注释驱动的方法中,我所能做的就是测试异常类型 。 例如,在以后要添加更多测试的情况下,我无法对异常消息做出任何假设。 考虑一下:

// This:
try {ubyte((UByte.MIN_VALUE) - 1);fail("Reason for failing");
}
catch (NumberFormatException e) {assertEquals("some message", e.getMessage());assertNull(e.getCause());...
}

3.单一方法调用不是单位

单元测试称为testValueOfIntInvalid() 。 因此, 通常在输入无效的情况下,要测试的语义“单位”是UByte类型的valueOf()行为的语义“单位”。 不适用于单个值,例如UByte.MIN_VALUE - 1

不应将其拆分为更小的单元,仅仅是因为这是我们可以将@Test注释刺入其功能范围的唯一方法。

TDD伙计们,请听听。 我从不希望将我的API设计或我的逻辑塞进由“向后”测试框架(不是个人的,JUnit)强加的一些怪异的限制。 永不 ! “我的” API比“您的”测试重要100倍。 这包括我不想:

  • 公开一切
  • 使一切都没有定论
  • 使一切都可以注射
  • 使所有内容均为非静态
  • 使用注释。 我讨厌注解。

不。 你错了。 Java已经不是一种太复杂的语言,但是让我至少可以使用我想要的任何方式使用它提供的一些功能。

不要因为测试而在我的代码上强加您的设计或语义上的毁损。

好。 我React过度了。 我总是在带有批注的情况下 。 因为…

4.对于控制流结构而言,注释始终是错误的选择

一次又一次,我为Java生态系统中的注释滥用而感到惊讶。 注释对于三件事有好处:

  1. 可处理的文档(例如@Deprecated
  2. 方法,成员,类型等的自定义“修饰符”(例如@Override
  3. 面向方面的编程(例如@Transactional

并且要注意,@ @Transactional是使其成为主流的少数几个真正有用的方面之一(日志挂钩是另一个方面,或者,如果绝对必须的话,可以进行依赖注入)。 在大多数情况下,AOP是解决问题的利基技术,您通常在普通程序中不希望这样做。

用注解对控制流结构进行建模绝对不是一个好主意,更不用说测试行为了

是。 Java已经采用了很长的(缓慢的)方法来包含更复杂的编程习惯。 但是,如果您对单元测试中偶尔的try { .. } catch { .. }语句的冗长内容感到不满,那么您可以找到解决方案。 是Java 8。

如何用Java 8更好地做

JUnit lambda正在开发中: http : //junit.org/junit-lambda.html

他们将新的功能性API添加到新的Assertions类中: https : //github.com/junit-team/junit-lambda/blob/master/junit5-api/src/main/java/org/junit/gen5/api /Assertions.java

一切都基于Executable功能接口 :

@FunctionalInterface
public interface Executable {void execute() throws Exception;
}

该可执行文件现在可以用于实现断言引发(或不引发)异常的代码。 请参见Assertions的以下方法

public static void assertThrows(Class<? extends Throwable> expected, Executable executable) {expectThrows(expected, executable);
}public static <T extends Throwable> T expectThrows(Class<T> expectedType, Executable executable) {try {executable.execute();}catch (Throwable actualException) {if (expectedType.isInstance(actualException)) {return (T) actualException;}else {String message = Assertions.format(expectedType.getName(), actualException.getClass().getName(),"unexpected exception type thrown;");throw new AssertionFailedError(message, actualException);}}throw new AssertionFailedError(String.format("Expected %s to be thrown, but nothing was thrown.", expectedType.getName()));
}

而已! 现在,那些反对try { .. } catch { .. }块的冗长的人可以重写此代码:

try {ubyte((UByte.MIN_VALUE) - 1);fail("Reason for failing");
}
catch (NumberFormatException e) {}

…进入:

expectThrows(NumberFormatException.class, () -> ubyte((UByte.MIN_VALUE) - 1));

如果我想对异常进行进一步检查,可以这样做:

Exception e = expectThrows(NumberFormatException.class, () -> ubyte((UByte.MIN_VALUE) - 1));
assertEquals("abc", e.getMessage());
...

出色的工作,JUnit lambda团队!

函数式编程每次都会击败注释

注释被滥用了很多逻辑 ,主要是在JavaEE和Spring环境中,它们都非常渴望将XML配置移回Java代码。 这是错误的方法,这里提供的示例清楚地表明,与使用批注相比,几乎总是有一种更好的方法可以使用面向对象或功能编程来显式地写出控制流逻辑。

@Test(expected = ...)的情况下,我得出结论:

安息, expected

(无论如何,它不再是JUnit 5 @Test批注的一部分)

翻译自: https://www.javacodegeeks.com/2016/01/use-junits-expected-exceptions-sparingly.html

junit 预期错误

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

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

相关文章

LeetCode 231. 2的幂

原题链接 class Solution { public:bool isPowerOfTwo(int n) {if(n<0)return false;if((n&n-1) 0) return true;return false;} };

睡眠 应该用 a加权 c加权_在神经网络中提取知识:学习用较小的模型学得更好...

在传统的机器学习中&#xff0c;为了获得最先进的(SOTA)性能&#xff0c;我们经常训练一系列整合模型来克服单个模型的弱点。 但是&#xff0c;要获得SOTA性能&#xff0c;通常需要使用具有数百万个参数的大型模型进行大量计算。 SOTA模型(例如VGG16 / 19&#xff0c;ResNet50)…

matlab读txt文件不完整,求助Matlab批量读取TXT文件出错

我用dlmread函数批量读取txt文件中的一个数据&#xff0c;但运行结果1.txt文件中只有一个数据0&#xff0c;调试时报错&#xff1a;错误使用 dlmread (line 147)文件结尾不支持空的格式字符串&#xff0c;文件有128列&#xff0c;78行&#xff0c;下面没有列全文件格式是&#…

面向对象代码_面向对象的代码生成方法

面向对象代码代码生成是减少无聊任务的不健康负担的一种常用方法&#xff0c;这些任务常常使我们急切地对代码苦恼。 我见过的许多代码生成框架都使用模板替换重复方法&#xff0c;在该模板中&#xff0c;您编写了模板&#xff0c;以了解生成的代码文件的外观&#xff0c;然后替…

LeetCode 20.有效括号

原题链接 方法一&#xff1a;解题思路&#xff0c;使用栈 模拟法&#xff1b;首先遍历将是左括号形式的部分压入栈中。然后对于右括号形式与栈顶元素进行比对&#xff0c;看是否匹配。如果匹配的话删除栈顶元素&#xff0c;不匹配直接返回false。最后栈为空则全部的括号匹配…

gpu编程如何一步步学习_如何学习贴片机编程

学习贴片机编程首选要对贴片机有所熟悉了解&#xff0c;另外对常用的电脑编辑软件要会使用。目前通常学习贴片机编程有专门的培训学校&#xff0c;或者跟着生产线上现有的贴片机编程师傅学习熟练后再进行编程操作。下面深圳智驰科技就来分享一下如何学习贴片机编程。对贴片机编…

plotcylinder matlab,Matlab在任意两点之间绘制三维圆柱

Matlab在任意两点之间绘制三维圆柱Matlab在任意两点之间绘制三维圆柱此函数可能存在一些不足&#xff0c;请多多指教&#xff01;function plotcylinder(u1,u2,color_a,r)Lnorm(u1-u2);RODu2-u1;[X,Y,Z]cylinder(r,100);x1X*0;y1Y*0;z1Z*0;ZL*Z-L/2;ROD_midpoint(u1u2)/2;xROD_…

简单内存池设计

关键词 内存池 链表 class A { public:static void* operator new(size_t size);static void operator delete(void* phead);static int m_iCout;//分配计数统计&#xff0c;每new一次&#xff0c;就统计一次static int m_iMallocCount;//每次malloc一次&#xff0c;统计一次p…

jdk8和hotspot_HotSpot的-XshowSettings标志的简单性和价值

jdk8和hotspot一个方便的HotSpot JVM标志 &#xff08; 选项为Java启动 java &#xff09;是-XshowSettings选项。 Oracle Java启动器描述页面中对此选项进行了如下描述 &#xff1a; -XshowSettings &#xff1a; category显示设置并继续。 该选项的可能类别参数包括&#xf…

怎样自动提取邮件的内容_这些最新的外贸搜索开发工具(图灵搜、谷歌搜索提取工具、易查查),你会使用吗?...

贸业务开展过程中&#xff0c;搜寻买家信息&#xff0c;开发买家客户&#xff0c;是开展外贸的前提。而掌握B2B、谷歌、搜索引擎、社交网站及众多搜索工具的运用技巧&#xff0c;则是外贸业务人员的基本功。本篇文章将结合图灵搜、谷歌搜索提取工具、易查查&#xff0c;三款工具…

LeetCode 面试题55 二叉树的深度

原题链接 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { public:int maxDepth(TreeNode* root) {if(rootNULL)…

matlab信号分割与比对,matlab测量计算信号的相似度

本示例说明如何测量信号相似度。将回答以下问题&#xff1a;如何比较具有不同长度或不同采样率的信号&#xff1f;如何确定测量中是否存在信号或仅有噪声&#xff1f;有两个信号相关吗&#xff1f;如何测量两个信号之间的延迟&#xff1f;比较具有不同采样率的信号考虑一个音频…

Spring Bootstrap中具有配置元数据的高级配置

在简要介绍了配置元数据并涵盖了我之前的文章《 在Spring Boot中使用配置元数据Pimp您的配置》中的基础知识之后&#xff0c;现在该看看如何进一步执行此步骤并进一步自定义配置。 在这篇文章中&#xff0c;我计划提出对配置属性的弃用&#xff0c;并讨论各种值提供程序&#x…

ssh 与 telnet 有何不同?_采用创新面料Nike Infinalon的全新瑜珈系列究竟有何不同?...

采用创新面料Nike Infinalon的全新瑜珈系列究竟有何不同&#xff1f;无拘无束自由运动——这是耐克瑜伽系列新品的核心设计理念。全新系列为你提供垫上瑜伽时毫无束缚的舒适感&#xff0c;采用了耐克创新型面料&#xff1a;Nike Infinalon。Nike Infinalon应用于耐克最新瑜伽系…

matlab中的导函数驻点,Matlab用导数作定性分析

Matlab用导数作定性分析5.1知识要点&#xff1a;函数作图 —用导数定性描述函数【 clf,xlinspace(-8,8,30);f(x-3).^2./(4*(x-1)); plot(x,f) 】【 fplot((x-3)^2/(4*(x-1)),[-8,8])) 】【 clf,xsym(x); f(x-3)^2/(4*(x-1)); ezplot(f,[-8,8]) ,ti…

java lambda循环_使用Java 8 Lambda简化嵌套循环

java lambda循环对于每个经常需要在Java 8&#xff08;或更高版本&#xff09;中使用多维数组的人来说&#xff0c;这只是一个快速技巧。 在这种情况下&#xff0c;您可能经常会以类似于以下代码的结尾&#xff1a; float[][] values ... for (int i 0; i < values.leng…

原生态基于OpenCV图像处理软件开发

部分功能效果图 GitHub:https://github.com/CnYiXiaoNaiHe/OpenCV- 持续更新

git.exe 启动 慢_四川成都surface电脑启动到一半黑屏维修服务地址电话

联系人&#xff1a;刘工 欢迎来电 地址&#xff1a;成都市一环路南二段1号(磨子桥口)数码科技大厦(新世纪电脑城对面)4楼413专业surface全系列维修因为专注&#xff0c;所以专注&#xff0c;所以surface配件都有现货。微软电脑&#xff0c;微软平板电脑专业维修服务点surface R…

php7.1 split,PHP 函数 split()

函数array split (string pattern, string string [, int limit])定义和用法返回一个字符串数组&#xff0c;每个单元为 string 经区分大小写的正则表达式 pattern 作为边界分割出的子串。如果设定了 limit&#xff0c;则返回的数组最多包含 limit 个单元&#xff0c;而其中最后…

java永生代和新生代_Java:永生的对象和对象的复活

java永生代和新生代什么是物体复活&#xff1f; 当没有其他对象引用该对象时&#xff0c;该Java对象可以进行垃圾回收。 当JVM&#xff1a;s垃圾收集器最终将要删除未使用的对象时&#xff0c;将调用该对象的finalize()方法。 但是&#xff0c;如果我们再次使用对象自己的final…