java 单元测试技巧

在我以前的文章中,我展示了有关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

java 单元测试技巧

java 单元测试技巧_其他一些单元测试技巧相关推荐

  1. maven 单元测试并行_并行运行单元测试

    maven 单元测试并行 大约是时候单元测试的开发人员能够使用批注在Parallel中运行测试. 在今天的博客文章中,我们将介绍如何使用Easytest提供的注释使传统的Junit测试并行运行. 易测 ...

  2. java 短路判断_随笔 | 奇淫技巧 | Java:记 return 和短路运算符的妙用

    在阅读 AtomicStampedReference 的源码中,在 compareAndSet() 方法发现一段代码: return expectedReference == current.refe ...

  3. sql优化技巧_使用这些查询优化技巧成为SQL向导

    sql优化技巧 成为SQL向导! (Become an SQL Wizard!) It turns out storing data by rows and columns is convenient ...

  4. python代码技巧_几个小技巧让你的Python代码更Pythonic

    Python是一门非常灵活的语言,很多语法是其他语言不具备的,特别是对于从C.Java等语言转向Python的人来说,很容易按照C.Java等语言的写法来写Python,对于初学者来说,如果对Pyth ...

  5. 使用技巧_信用卡的使用技巧

    点击蓝字 关注我们 导语 在信用卡普及的今天,谁没几张信用卡防身呢? 但是用卡技巧没掌握好,轻则被降额,重则被封卡.掌握好用卡姿势,不但不会封卡降额,还会对提额有很大帮助. 一 更改账单日,延长免息期 ...

  6. 12天背诵楞严咒的技巧_背诵楞严咒的技巧

    本文整理自网络,内容仅作公益性分享. 楞严咒出自<楞严经>,全称"佛顶光明摩诃萨怛多般怛蓝无上神咒". <楞严咒>是咒中之王,佛经上说这个咒关系整个佛教的兴 ...

  7. 可以进行单元测试么_前端与单元测试

    先来几个专业词汇,这样显得高大上一点(不存在的=.=) BDD: Behavior-Driven Development (行为驱动开发)TDD: Test-Driven Development (测 ...

  8. 1使用技巧_新版PubMed使用技巧1

    以下分享适合小白,高手请绕路. PubMed是许多医学生以及科研人员必备的检索系统,高效的利用PubMed可以节省很多时间.本文从以下几个方面简单讲解新版PubMed的使用技巧1:1.PubMed基本 ...

  9. 日志查看技巧_如何用 Linux 技巧大大提高工作效率?

    前言 Linux中的一些小技巧可以大大提高你的工作效率,本文就细数那些提高效率或者简单却有效的Linux技巧. 命令编辑及光标移动 这里有很多快捷键可以帮我们修正自己的命令.接下来使用光标二字代替光标 ...

最新文章

  1. 那个大战AlphaGo的柯洁,将免试入读清华大学工商管理专业
  2. opencv java库_【OpenCV】java资源
  3. Swagger Learing - Spring Boot 整合swagger
  4. Java虚拟机笔记(五):JVM中对象的分代
  5. 异常处理第一讲(SEH),筛选器异常,以及__asm的扩展,寄存器注入简介
  6. 不足 20 行 Python 代码,高效实现 k-means 均值聚类算法!
  7. 芯片之战!亚马逊、Google、苹果群起“围攻”英特尔
  8. java long类型6_Java学习6——基本数据类型及其转换
  9. 华为手机下拉菜单变大_华为手机如何设置下拉菜单顺序 原来是这样的
  10. 计算机串口故障,电脑故障:主板串口接口故障的维修方法总结
  11. unity中单位是米还是厘米_厘米和米都是什么单位
  12. 虚拟机无法连接到图形服务器,vmware vsphere client无法连接到服务器
  13. 微信小程序合集源码I(机器人聊天+仿别踩白块儿小游戏+仿步步高电子词典+仿知乎+日记+汉字拼音+转盘抽奖)
  14. 怎么把录音导入库乐队_库乐队导入音乐的具体流程讲述
  15. MySQL中三种表关系的建立
  16. 怎样将word标尺调出来?word标尺的使用技巧!
  17. RocketMQ 分布式事务消息过程分析
  18. 统一通信概念鱼龙混杂
  19. 服务器宕机记录16.12.14
  20. Error: unknown pseudo-op: `.arch_extension'

热门文章

  1. P2048-[NOI2010]超级钢琴【RMQ,堆】
  2. jzoj4227-B【dp,字符串】
  3. jzoj2700-数字【数论,LCM】
  4. ssl1202-滑雪【记忆化搜索法】
  5. codeforces1486 F. Pairs of Paths(倍增+树上数数)
  6. Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例
  7. 数据结构(一)之链表
  8. 《走遍中国》珍藏版(十三)
  9. 当字段过长,鼠标移上去才展示全部,默认只展示部分防止表格比例发生变化
  10. 程序员成长之路 java面试指导(作者说的极好要看) 静下心看