JUnit规则–引发异常时执行附加验证

在本文中,我将快速向您展示如果您需要解决以下挑战,那么JUnit规则有多方便

方法捕获异常并必须执行一些额外的任务,然后再抛出或引发包装异常。
调用额外任务和引发的异常应通过单元测试进行验证。

这意味着您有一些这样的代码

public class MyThrowingClass {private final ExceptionProcessor exceptionProcessor;public MyThrowingClass(ExceptionProcessor exceptionProcessor) {this.exceptionProcessor = exceptionProcessor;}public void runTask() throws NullPointerException {try {// something to do herethrow new NullPointerException("It's null Jim");} catch (NullPointerException e) {exceptionProcessor.process(e); // This call needs to be verifiedthrow e;}}
}

并在这行中

exceptionProcessor.process(e);

需要进行验证以及引发异常。

直截了当…但是丑陋

我不会详细介绍此变体

try {cut.runMyMethod();
} catch(Exception e) {verify(...);assertThat(e).isInstanceOf();
}

因为我个人尽量避免在测试代码中尝试捕获结构。

容易的第一

验证引发异常相当容易,JUnit在此处提供了潜在的选项

  1. @Test批注的预期参数和
  2. 一个叫做ExceptionRule的规则

第一个选项看起来像这样

@Test(expected = NullPointerException.class)
public void myTestWithExpectedParameter() throws Exception {// ...
}

第二个像这样

// ... 
@Rule
public ExceptionRule exceptionRule = ExceptionRule.none();// ...@Test
public void myTestWithTheExceptionRule() throws Exception {exceptionRule.expect(NullPointerException.class);// ...
}

不,它变得越来越复杂

上述测试要求背后的问题如下

执行被测方法之后,您执行的所有verify(…)步骤将不会执行,因为如果引发并没有捕获到异常,异常将照常停止其余测试方法的执行。

JUnit救援规则

借助JUnit规则,我们即使在引发异常的情况下,也可以轻松地提供一种提供其他验证步骤的方法。

我知道JUnit已经提供了验证程序规则,但是我不会使用它。 该类的缺点是在设置时将验证逻辑刻录到其中。

因此,我们需要一个规则,该规则允许我们为每个测试指定一个额外的验证逻辑,该逻辑将在测试执行后应用。

一般用法如下所示

@Rule
public VerifyRule verifyRule = new VerifyRule();@Mock
ExceptionProcessor exceptionProcessor;@Test()
public void working() throws Exception {verifyRule.setVerifier(() -> verify(exceptionProcessor).process(any()));// ..
}

为了使它运行起来,我们需要做一些事情

  • 验证规则
  • 可以在验证规则上设置的任何类型的回调接口

让我们从回调接口开始

public interface VerifyRuleCallback {void execute() throws Throwable;
}

如您所见,这里没什么特别的。

现在,让我们专注于VerifyRule

public class VerifyRule implements TestRule {private VerifyRuleCallback verifyRuleCallback;@Overridepublic Statement apply(Statement base, Description description) {return new VerifyRuleStatement(base);}public void setVerifier(VerifyRuleCallback verifyRuleCallback) {this.verifyRuleCallback = verifyRuleCallback;}private class VerifyRuleStatement extends Statement {private final Statement nextStatement;public VerifyRuleStatement(Statement nextStatement) {this.nextStatement = nextStatement;}@Overridepublic void evaluate() throws Throwable {nextStatement.evaluate();verifyRuleCallback.execute();}}
}

如您所见,它实现了TestRule接口,并提供了一种设置VerifyRuleCallback的方法。 然后,在需要执行以运行我们自己的回调评估的VerifyRuleStatement的评估方法中使用该回调。

绑在一起

使用新规则和回调,测试可能看起来像这样

public class MyThrowingClassShould {@Rulepublic MockitoRule mockitoRule = MockitoJUnit.rule();@InjectMocksMyThrowingClass cut;@MockExceptionProcessor processor;@Rulepublic ExpectedException exception = ExpectedException.none();@Rulepublic VerifyRule verifyRule = new VerifyRule();@Test()public void execute_the_exception_processor_and_rethrow_the_exception_when_it_occur() throws Exception {verifyRule.setVerifier(() -> verify(processor).process(any(NullPointerException.class)));exception.expect(NullPointerException.class);cut.runTask();}
}

摘要

正如我们已经看到的那样,JUnit规则不仅在这种情况下,而且还提出了这样的测试要求时,提供了一种非常简洁的方法来创建清晰易懂的测试代码。

的JUnit 2016-09-26

彼得·道姆(Peter Daum)

翻译自: https://www.javacodegeeks.com/2016/09/junit-rules-executing-additional-verification-exceptions-thrown.html

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

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

相关文章

十分钟搞清字符集和字符编码

什么是字符集 什么是字符编码 UTF-8和Unicode的关系 UTF-8编码简介 为什么会出现乱码 如何识别乱码的本来想要表达的文字 常见问题处理之Emoji 本文将简述字符集,字符编码的概念。以及在遭遇乱码时的一些常用诊断技巧 背景:字符集和编码无疑是IT菜鸟甚至…

前端Ajax/JS/HTML+后端SpringMVC(二)

1. jQuery AJAX 1.1. jQuery框架中的ajax()函数 在应用了jQuery框架后,调用ajax()函数即可发出AJAX请求,并获取响应结果,该函数的参数必须是JSON对象,通常,在JSON对象中封装的属性有: url:处理请…

java lambda函数_番石榴函数和Java 8 Lambdas

java lambda函数我最近阅读了Brian Goetz的《 Lambda的状况》 ,在阅读了该文章之后,我想尝试使用Java 8 Lambda表达式。 Brian在他的文章中继续描述了将一种方法称为“功能”接口的接口。 功能接口几乎总是用作匿名类,其中ActionListener是规…

c++组合 聚合 关联

组合和聚合区别(不能脱离整体 能脱离整体) 组合:(表示两个对象之间是整体和部分的强关系,部分的生命周期不能超越整体。如人和脑袋) 比如A类中包含B类的一个引用b,当A类的一个对象消亡时,b这个引用所指向的…

python内建时间模块 time和datetime

时间模块 UTC(Coordinated Universal Time,世界协调时)亦即格林威治天文时间,世界标准时间。在中国为UTC8。DST(Daylight Saving Time)即夏令时。 在Python中,通常有这几种方式来表示时间:1&…

java tomcat自动安装教程_Tomcat:基础安装和使用教程

背景此文记录了 Tomcat 的基本使用方法,主要为了强化记忆。安装步骤第一步:下载和安装 Java安装并设置JAVA_HOME环境变量:第二步:下载和解压 Tomcat第三步:修改端口号.NET 我使用的是 80xx,Php 我使用的是 …

C++ 智能指针五

/* 代码分析:这是标准库的源码,我们看到在enable_shared_from_this内部保存了一个weak_ptr。shared_from_this函数就是通过这个weak_ptr得到了。 但是另外一点,我们可以看到在enable_shared_from_this的构造函数中并没有对这个weak_ptr进行初始化。 这就…

多线程之间共享的资源有哪些

搜集了一下资料,网上的说法众说纷纭;曾经以为进程、线程的问题搞得很清楚,现在感觉似乎有些复杂: 课本的说法:进程是资源分配的基本单位;线程是系统调度的基本单位。平时我们写的程序都是作为线程运行的&am…

mybatis一级缓存导致sql查询出现问题

如下代码: PubPsndoc pubdoc pubPsndocDAOService.selectByPrimaryKey(in.id);pubdoc.setPkCorp(newpkcorp);pubdoc.setPkDept(newpkdept);pubPsndocDAOService.update(pubdoc); PubPsndoc personPubdoc pubPsndocDAOService.selectByPrimaryKey(in.id); 在上述代…

使用JavaParser从源文件中提取JavaDoc文档

很多人正在使用JavaParser实现最不同的目标。 其中之一是提取文档。 在这篇简短的文章中,我们将看到如何打印与类或接口关联的所有JavaDoc注释。 可以在GitHub上找到代码: https : //github.com/ftomassetti/javadoc-extractor 获取类的所有Javadoc注释…

三个打印函数printf()/sprintf()/snprintf()区别

先贴上其函数原型 printf( const char *format, ...) 格式化输出字符串,默认输出到终端-----stdout sprintf(char *dest, const char *format,...) 格式化输出字符串到指定的缓冲区 snprintf(char *dest, size_t size,const char *format,...) 按指定的S…

JAVA客户端数据传输_java模拟TCP通信实现客户端上传文件到服务器端

java模拟TCP通信实现客户端上传文件到服务器端,供大家参考,具体内容如下客户端package com.zr;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.Socket;import jav…

js闭包简单演示

function f1() { var age 20; var height 170; function f2() { console.log("aaa:"(age) "--bbb:"height); } return f2; } var ff f1(); var fa f1(); fa(); fa(); ff(); ff(); 这里有两个闭包,fa和ff分别保存的信息独立,age…

C++ 类成员引用变量的使用

出来工作后&#xff0c;才发现原来C的类成员变量可以是引用变量。下面通过一个例子来说明&#xff08;虽然没多大意义&#xff09;&#xff1a; #include <iostream> using namespace std; class A { public: A(int i3):m_i(i){} void print() { c…

java 课程设计表达式求值_NYOJ-35-表达式求值

NYOJ-35-表达式求值很好的一题&#xff0c;利用栈来计算表达式的值四则运算的规则&#xff1a;1.先乘除,后加减&#xff1b;2.从左算到右&#xff1b;3.先括号内,后括号外注意把字符串转换成浮点数可以使用atof函数#include#include#includeint map[7][7] //算符间的优先关系,1…

打破冷漠僵局文章_研究僵局–第3部分

打破冷漠僵局文章在本系列的前两个博客&#xff08; 第1部分和第2部分&#xff09;中 &#xff0c;我演示了如何创建一段会死锁的错误代码&#xff0c;然后使用该代码演示进行线程转储的三种方式。 在此博客中&#xff0c;我将分析线程转储以找出错误的原因。 下面的讨论同时涉…

springboot 静态资源访问,和文件上传 ,以及路径问题

springboot 静态资源访问: 这是springboot 默认的静态资源访问路径 访问顺序依次从前到后&#xff08;http://localhost:8080/bb.jpg&#xff09; spring.resources.static-locations classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/p…

mysql jdbc链接配置文件_Java JDBC使用配置文件连接数据库

Java JDBC使用配置文件连接数据库&#xff1a;创建后缀名为&#xff1a;.properties的文件&#xff0c;文件内容包括&#xff0c;数据库驱动、连接的数据库地址、用户名、密码……以Mysql为例创建config.properties配置文件其内容如下&#xff1a;DRIVER_CLASScom.mysql.jdbc.D…

单例模式(饿汉式和懒汉式)

以前学习单例的时候&#xff0c;只理解了简单部分。这次看DRP&#xff0c;对单例的饿汉式和懒汉式有了一些认识和对比。 在实际的开发中&#xff0c;有些地方需要一个类只有一个实例。比如&#xff1a;网站在线人数的计数器&#xff0c;再比如IDE中的工具箱之类的等等。当需要这…

关于前端设置cookie

cookie既可以后端设置也可以在前端设置&#xff0c;例如登陆/注册功能&#xff0c;每次都要向服务器请求用户数据&#xff0c;这种就可以把cookie放到前端储存起来。 当网页要发http请求时&#xff0c;浏览器会先检查是否有相应的cookie&#xff0c;有则自动添加在request head…