其他一些单元测试技巧

在我以前的文章中,我展示了有关JavaBeans单元测试的一些技巧。 在此博客文章中,我将提供有关单元测试某些相当常见的Java代码的另外两个技巧,即实用程序类Log4J日志记录语句

测试实用程序类

如果您的实用程序类遵循与我倾向于编写的相同的基本设计,则它们由带有私有构造函数和所有静态方法的最终类组成。



实用类测试仪

package it.jdev.example;import static org.junit.Assert.*;import java.lang.reflect.*;import org.junit.Test;/*** Tests that a utility class is final, contains one private constructor, and* all methods are static.*/
public final class UtilityClassTester {private UtilityClassTester() {super();}/*** Verifies that a utility class is well defined.* * @param clazz* @throws Exception*/@Testpublic static void test(final Class<?> clazz) throws Exception {// Utility classes must be final.assertTrue("Class must be final.", Modifier.isFinal(clazz.getModifiers()));// Only one constructor is allowed and it has to be private.assertTrue("Only one constructor is allowed.", clazz.getDeclaredConstructors().length == 1);final Constructor<?> constructor = clazz.getDeclaredConstructor();assertFalse("Constructor must be private.", constructor.isAccessible());assertTrue("Constructor must be private.", Modifier.isPrivate(constructor.getModifiers()));// All methods must be static.for (final Method method : clazz.getMethods()) {if (!Modifier.isStatic(method.getModifiers()) && method.getDeclaringClass().equals(clazz)) {fail("Non-static method found: " + method + ".");}}}}

该UtilityClassTester本身也遵循上面提到的实用程序类约束,因此有什么更好的方法通过使用它来测试自身来证明其用途:

UtilityClassTester的测试用例

package it.jdev.example;import org.junit.Test;public class UtilityClassTesterTest {@Testpublic void test() throws Exception {UtilityClassTester.test(UtilityClassTester.class);}}

测试Log4J记录事件

调用声明异常的方法时,您将重新声明该异常,或者尝试在try-catch块中对其进行处理。 在后一种情况下,至少要做的是记录捕获的异常。 下面是一个非常简单的示例:

MyService示例

package it.jdev.example;import java.lang.invoke.MethodHandles;import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class MyService {private static final Logger LOGGER = Logger.getLogger(MethodHandles.Lookup.class);@Autowiredprivate MyRepository myRepository;public void doSomethingUseful() {try {myRepository.doSomethingVeryUseful();} catch (SomeException e) {LOGGER.error("Some very informative error logging.", e);}}}

当然,您将需要测试是否正确记录了异常。 遵循以下内容:

MyService日志记录事件的测试用例

package it.jdev.example;import static org.junit.Assert.*;import org.apache.log4j.spi.LoggingEvent;
import org.junit.*;
import org.mockito.*;public class MyServiceTest {@Mockprivate MyRepository myRepository;@InjectMocksprivate MyService myService = new MyService();@Beforepublic void setup() {MockitoAnnotations.initMocks(this);}@Testpublic void thatSomeExceptionIsLogged() throws Exception {TestAppender testAppender = new TestAppender();Mockito.doThrow(SomeException.class).when(myRepository).doSomethingVeryUseful();myService.doSomethingUseful();assertTrue(testAppender.getEvents().size() == 1);final LoggingEvent loggingEvent = testAppender.getEvents().get(0);assertEquals("Some very informative error logging.", loggingEvent.getMessage().toString());}}

但是,如何实现这一目标呢? 事实证明,将新的LogAppender添加到Log4J RootLogger非常容易。

用于Log4J的TestAppender

package it.jdev.example;import java.util.*;import org.apache.log4j.*;
import org.apache.log4j.spi.*;/*** Utility for testing Log4j logging events.* <p>* Usage:<br />* <code>* TestAppender testAppender = new TestAppender();<br />* classUnderTest.methodThatWillLog();<br /><br />* LoggingEvent loggingEvent = testAppender.getEvents().get(0);<br /><br />* assertEquals()...<br /><br />* </code>*/
public class TestAppender extends AppenderSkeleton {private final List<LoggingEvent> events = new ArrayList<LoggingEvent>();public TestAppender() {this(Level.ERROR);}public TestAppender(final Level level) {super();Logger.getRootLogger().addAppender(this);this.addFilter(new LogLevelFilter(level));}@Overrideprotected void append(final LoggingEvent event) {events.add(event);}@Overridepublic void close() {}@Overridepublic boolean requiresLayout() {return false;}public List<LoggingEvent> getEvents() {return events;}/*** Filter that decides whether to accept or deny a logging event based on* the logging level.*/protected class LogLevelFilter extends Filter {private final Level level;public LogLevelFilter(final Level level) {super();this.level = level;}@Overridepublic int decide(final LoggingEvent event) {if (event.getLevel().isGreaterOrEqual(level)) {return ACCEPT;} else {return DENY;}}}}

翻译自: https://www.javacodegeeks.com/2014/09/some-more-unit-test-tips.html

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

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

相关文章

常见的CSS布局

各种常见的CSS布局 在工作中会经常用到很多的布局方式&#xff0c;这里总结一下所遇到的布局&#xff0c;会持续更新。 悬挂布局 实现这种布局的方式有很多&#xff0c;这边主要挑两个&#xff0c;如下&#xff1a; 方式一&#xff1a;使用浮动和块级格式化上下文特性 这种…

netflix数据处理2(转)

原始数据&#xff1a;$head -10 mv_0006890.txt6890:1735266,1,2004-04-021008399,1,2004-06-222360117,2,2003-11-081294425,2,2004-03-15439931,4,2004-03-271583311,1,2004-03-112431832,3,2005-02-13620771,2,2004-03-201110906,1,2004-03-04结果数据&#xff1a;user_id m…

jQuery 效果

显示和隐藏 1. show(speed) &#xff1a;speed 可以取&#xff1a;slow/fast/毫秒 1 $("#show").click(function(){2 $("p").show(1000);3 }); 2. hide(speed) &#xff1a; 1 $("#hide").click(function(…

OSCP-Kioptrix2014-2 漏洞利用

pChart 2.1.3 文件包含漏洞 搜索漏洞查看漏洞理由代码:hxxp://localhost/examples/index.php?ActionView&Script%2f..%2f..%2fetc/passwd 之前的8080端口禁止访问,看看apache的配置:http://192.168.1.78/pChart2.1.3/examples/index.php?ActionView&Script%2f..%2f..…

使用Drools跟踪输出

Drools 6包含一个跟踪输出&#xff0c;可以帮助您了解系统中正在发生的事情&#xff0c;事物执行的频率以及多少数据。 这也有助于理解Drools 6现在是基于目标的算法&#xff0c;它使用链接机制链接评估规则。 有关此的更多详细信息&#xff1a; http://www.javacodegeeks.co…

CodeSmith注册机,支持5.2.2和5.2.1版

CodeSmith&#xff0c;不用说了&#xff0c;大名鼎鼎的代码生成工具。最早是免费的&#xff0c;后来收费啦这个注册机是针对目前新的CodeSmith 5.2.2的&#xff0c;支持Professinal和其他版本。使用的方法&#xff1a;安装原版的试用版本&#xff0c;从官方网站下载运行试用版&…

JS中与正则相关的方法

前面有一篇文章大体介绍了一下JS中正则表达式&#xff0c;而使用正则表达式还需要配合JS中的相关方法&#xff0c;分别是String对象和RegExp对象的方法。今天就来具体介绍一下这些方法。 使用这则表达式的方法可以分为两类&#xff0c;一个是String的几个方法&#xff0c;还有…

JS基础:求一组数中的最大最小值,以及所在位置

1 var arr [0, 5, -3, 6, 2, -6, 10];2 //定义一个最大值和一个最小值&#xff0c;把他们的索引值赋值给固定的两个变量3 var maxValue arr[0];4 var minValue arr[0];5 var maxIndex 0;6 var minIndex 0;7 for …

linux epoll,poll,select

epoll函数用法&#xff0c;还有点poll和select 1&#xff0c;LT的epoll是select和poll函数的改进版。 特点是&#xff0c;读完缓冲区后&#xff0c;如果缓冲区还有内容的话&#xff0c;epoll_wait函数还会返回&#xff0c;直到把缓冲区全部读完。 2&#xff0c;ET的epoll&#…

λ和副作用

总览 Java 8添加了诸如lambda和类型推断之类的功能。 这使语言不那么冗长和简洁&#xff0c;但是它带来了更多的副作用&#xff0c;因为您不必对所做的事情那么明确。 Lambda的返回类型很重要 Java 8推断闭包的类型。 一种方法是查看返回类型&#xff08;或是否返回任何内容&a…

sessionStorage和localStorage的用法,不同点和相同点

一&#xff0c;共同点 &#xff08;1)存储时用setItem: localStorage.setItem("key","value");//以“key”为名称存储一个值“value”sessionStorage.setItem("key", "value"); &#xff08;2&#xff09;获取时用getItem: localS…

shell学习笔记1-文件安全与权限

1&#xff0c;创建文件的用户和他所属的组拥有该文件&#xff0c;文件的属主可以设定谁具有读、写、执行该文件的权限&#xff0c;根用户可以改变任何普通用户的设置。 2&#xff0c;一个文件一经创建&#xff0c;就具有三种访问权限&#xff1a;读&#xff08;可以显示该文件的…

没有IF-ELSE的工厂

面向对象语言具有非常强大的多态性功能&#xff0c;用于删除代码中的if / else或切换大小写。 没有条件的代码易于阅读。 在某些地方必须放置它们&#xff0c;其中一个示例是Factory / ServiceProvider类。 我敢肯定&#xff0c;您已经看到IF-ELSEIF的工厂课程了&#xff0c;…

最新70佳单页网站设计案例欣赏(上篇)

单页网站是指只有一个页面的网站&#xff0c;这种形式的网站曾经非常流行&#xff0c;现在依然有很多人喜欢。不过&#xff0c;并不是每个网站都适合做成单页&#xff0c;一般都是内容比较少而且将来内容也不怎么增加的情况才适合这样做。如果你打算做一个这样的网站&#xff0…

浏览器劫持者

launchpage 浏览器劫持者&#xff0c;它会在未经你的许可下就接管你的浏览器。更多 https://launchpage.org/?uidqT5KGGjMhxpsXWEzIkWR44y5McmHTuSG50ukahoC8gOClKIGNwZP0nuyPBoYUFiBINK7 https://ns.freedrive.cn/?sEB5805AD0&ghttp://item.jd.com/13300636764.html 更…

Kubernetes 中文文档

Kubernetes 中文文档 如果想学习 Kubernetes 的小伙伴&#xff0c;可以参考如下文档学习&#xff1a; https://www.kubernetes.org.cn/docs 文档中详细讲解了 k8s 的设计理念&#xff0c;基本概念&#xff0c;常用命令等。 转载于:https://www.cnblogs.com/miracle-luna/p/1111…

Edge 浏览器

Edge浏览器设计理念 无法播放&#xff1a;https://edgewelcomecdn.microsoft.com/site/images/tabs/rs3/tabs_screen.acd367a2.mp4 控制台消息 WEBGL11256: 检测到 GPU 重置。正在临时切换到软件呈现 WEBGL11056: 遇到的错误太多&#xff0c;将不再记录更多错误 Intersecti…

为什么NULL是错误的?

Java中NULL用法的简单示例&#xff1a; public Employee getByName(String name) {int id database.find(name);if (id 0) {return null;}return new Employee(id); }这种方法有什么问题&#xff1f; 它可能返回NULL而不是对象-这是错误的。 在面向对象的范例中&#xff0c…

网易原来也是个骗子

当初开通photo.163.com网易相册时&#xff0c;就是看着网易的宣传口号&#xff1a;免费而且不限容量&#xff01;结果现在坏了&#xff0c;规则说改就改&#xff0c;容量一下子收到1G&#xff0c;超过部份要么给钱&#xffe5;&#xffe5;&#xffe5;&#xffe5;&#xffe5…

不同设备屏幕尺寸和DPR适配

为什么需要适配 目前市面上设备屏幕属性十分多样化&#xff08;宽度和DPR并不一致&#xff09;&#xff0c;而作为设计和前端开发&#xff0c;无法为每个尺寸的设备单独设计一套UI并将其转为前端代码&#xff0c;这不现实。所以我们需要一套方案来将一套设计稿完美呈现在不同尺…