写接口的目的一般是,让这个接口的所有实现都具备某个共同的行为。这个行为不仅目前实现的类具备,将来要写的实现也都必须具备。因此,就需要为这个接口编写一个通用的测试程序,这个测试程序不仅能测试当前已经实现的类的通用属性,而且可以不加修改应用于将来要实现的类。

首先引入一个抽象的测试类,该测试类的方法用于测试接口的共同行为。然后使用工厂方法创建接口的对象,以完成测试程序。下面是详细步骤:

1.     选定测试程序要测试的已经具体实现的类。

2.     创建一个抽象的测试类,声明要验证的功能的测试方法。在具体的测试程序实现中继承这个测试类,并修改相应的实现方法。

3.     在接口的每一个具体实现中都运行该测试程序,但在每个实现中都只验证“接口范围内”的行为[10]。

4.     在测试程序内,找到创建(接口)对象的代码,将该代码改成具体的、已经实现的类的创建方法,但记住将该对象声明为接口的对象,而不是具体实现的类的对象。重复这一过程,直至测试程序中没有已经实现的类的对象。

5.     声明你要在测试中调用的抽象方法。

6.     现在,测试只涉及接口和一些抽象的测试方法,请将测试程序移入抽象的测试类。

7.     重复这一过程直至所有的测试都移入抽象的测试类。

8.     重复前面的全部过程,直至除了验证具体实现的特有的方法的测试程序外,所有的测试代码都已完成。

下面通过测试java.util.Iterator接口来具体说明这种技巧。首先让我们看代码ListIteratorTest,这是测试java.util.Listiterator接口的一个具体实现。

package junit.cookbook.test;

import java.util.ArrayList;

import java.util.Iterator;

import java.util.List;

import java.util.NoSuchElementException;

import static org.junit.Assert.*;

import org.junit.After;

import org.junit.Before;

import org.junit.Test;

public class ListIteratorTest {

private Iterator noMoreElementsIterator;

protected abstract Iterator makeNoMoreElementsIterator();

@Before

public void setUp() throws Exception {

List empty = new ArrayList();

noMoreElementsIterator = empty.iterator();

}

@Test

public void testHasNextNoMoreElements() {

assertFalse(noMoreElementsIterator.hasNext());

}

@Test

public void testNextNoMoreElements() {

try {

noMoreElementsIterator.next();

fail("No exception with no elements remaining!");

} catch (NoSuchElementException expected) {

}

}

@Test

public void testRemoveNoMoreElements() {

try {

noMoreElementsIterator.remove();

fail("No exception with no elements remaining!");

} catch (IllegalStateException expected) {

}

}

}

接着让引入抽象的IteratorTest测试类,并将ListIteratorTest类的实际的实现添加到IteratorTest。结果如下所示:

package junit.cookbook.test;

import java.util.Iterator;

import java.util.NoSuchElementException;

import static org.junit.Assert.*;

import org.junit.After;

import org.junit.Before;

import org.junit.Test;

public abstract class IteratorTest {

private Iterator noMoreElementsIterator;

protected abstract Iterator makeNoMoreElementsIterator();

@Before

public void setUp() throws Exception {

noMoreElementsIterator = makeNoMoreElementsIterator();

}

@Test

public void testHasNextNoMoreElements() {

assertFalse(noMoreElementsIterator.hasNext());

}

@Test

public void testNextNoMoreElements() {

try {

noMoreElementsIterator.next();

fail("No exception with no elements remaining!");

} catch (NoSuchElementException expected) {

}

}

@Test

public void testRemoveNoMoreElements() {

try {

noMoreElementsIterator.remove();

fail("No exception with no elements remaining!");

} catch (IllegalStateException expected) {

}

}

}

只要我们实现了makeNoMoreElementsIterator()方法,我们就可以将所有的测试移入IteratorTest类。我们只需要将这个方法封装到ListIteratorTest类中:

package junit.cookbook.test;

import java.util.ArrayList;

import java.util.Iterator;

import java.util.List;

import org.junit.After;

import org.junit.Before;

import temp.IteratorTest;

public class ListIteratorTest extends IteratorTest {

protected Iterator makeNoMoreElementsIterator() {

List empty = new ArrayList();

return empty.iterator();

}

}

ListIteratorTest继承我们的抽象类IteratorTest。

我们的ListIteratorTest类中实现的创建方法返回一个iterator而不是一个空列表。类似地,如果以测试一个基于Set类的iterator,你应该创建一个继承IteratorTest的SetIteratorTest类,这个类的makeNoMorelementsterator()方法也应该返回相应的iterator而不是一个空的Set对象。

这个抽象的test case能正常工作的原因是Junit中的测试等级规定。一个TestCase类在继承其父类时将同时继承父类所有的测试。在例子中,ListIteratorTest继承IteratorTest,所以只要在test runner中运行ListIteratorTest,IteratorTest中的测试都将得到运行。

值得一提的是Eric Armstrong的观点,他是Yahoo!的JUnit社区常客:“一个接口只定义语法,而不指定语义,虽然他们经常被实现。另一方面,一个相关的test Suite可以指定语义。我们应该给每一个公用的接口配备一个test suite!”当我们在框架中发布一个接口或者抽象类的时候,最好同时写一个相关的抽象的Test Case,以验证框架在所有客户端中的最重要的期望值。

最后,你会有同时实现了多个接口的类。建议你独立地测试每个接口的功能,而不要拘泥于那个“一个test case类测试一个类”的死板规定。

转载于:https://www.cnblogs.com/Automation_software/archive/2011/01/24/1943054.html

Junit实现接口类测试相关推荐

  1. Idea+JUnit+JUnitGenerator,生成自动测试类(可测试controller)

    Idea+JUnit+JUnitGenerator,生成自动测试类(可测试controller) 1.安装JUnitGenerator插件 打开Settings窗口搜索junit,如图: JUnitG ...

  2. Junit如何进行多线程测试

    Junit和许多开源软件项目集成在一起,但是Junit执行多线程的单元测试有一些问题.这篇文章介绍Junit的一个扩展类库―――GroboUtils,这个类库被设计为来解决这些问题,并且使在Junit ...

  3. JUnit 5中的测试执行顺序

    一般实践认为,自动化测试应能够独立运行且无特定顺序,并且测试结果不应依赖于先前测试的结果. 但是在某些情况下,可以证明特定的测试执行顺序是正确的,尤其是在集成或端到端测试中. 默认情况下,在JUnit ...

  4. java单元测试异步不进去方法_java单元测试之如何实现异步接口的测试案例

    测试是软件发布的重要环节,单元测试在实际开发中是一种常用的测试方法,java单元测试主要用junit,最新是junit5,本人开发一般用junit4.因为单元测试能够在软件模块组合之前尽快发现问题,所 ...

  5. 设计模式:模板模式抽象类(abstract)设计和接口类(interface)设计

    1 简介 模板模式即程序按照固定模式(流程)运行,倒叙的方式设计程序: 将完整的流程拆分为独立的模块,多个模块组合出完整的功能: 模块化编程: 模板模式实现方式有两种: (1)抽象类: (2)接口类: ...

  6. robotframwork接口测试(五)—接口分层测试粗解

    个人小结,仅供参考. 接口测试很简单,但是很重要. 可以写代码,也可以用工具进行测试.工具说说就很多了,简单介绍一下我目前用过的几个能够测试接口的工具, Burpsuite:这类偏请求攻击类软件 Fi ...

  7. mybaits二:通过接口类,查询数据

    定义bean,对应数据库中的表 package com.atChina.bean;public class Employee {private Integer deptno;private Strin ...

  8. 软件测试——JUnit中的参数化测试

    2019独角兽企业重金招聘Python工程师标准>>> 参数化测试用于当需要使用多组不同的测试数据测试同一个方法的时候. 使用参数化测试的要点: ① 为该测试方法专门生成一个新的类: ...

  9. 存根类 测试代码 java_测试双打:模拟,假人和存根

    存根类 测试代码 java 大多数班级都有合作者. 在进行单元测试时,您通常希望避免使用那些协作者的实际实现方式来避免测试的脆弱性和绑定/耦合,而应使用测试双打:模拟,存根和双打. 本文引用了有关该主 ...

最新文章

  1. linux(ubuntu)~终端(terminal)shell操作指令
  2. JS模式--职责链模式
  3. Linux学习之系统编程篇:信号量(sem_init / wait / trywait / post / destroy)
  4. php框架 zend,模型部分的php设计模式[php zend框架]
  5. 试用GitHub Copilot一周后,我给你的建议是:不要使用它
  6. C语言编程 简单展开扫雷游戏
  7. 性能优化篇(2):不能忽视的DOM元素
  8. 原子结构示意图全部_原子结构示意图和元素及元素周期表
  9. 算术平均数及几何平均数
  10. 前端必备知识之 Nginx 复盘总结
  11. Going Deeper into Regression Analysis with Assumptions, Plots Solutions
  12. 论文解读:Predator-Pray biogeography Based Optimization (PPBBO)
  13. 用python实现纸牌游戏的随机抽牌洗牌过程(item系列几个内置方法的实例)
  14. java丧尸危机全城爆发_伤尸危机-全城爆发BT版
  15. 【信息安全案例】——身份与访问安全(学习笔记)
  16. MikTex中如何使用BibTeX添加参考文献
  17. 最喜欢的科技资讯类英文网站
  18. 运行在命令行的微信 cmd-wechat-terminal
  19. PHP单例模式(Singleton Pattern)
  20. Linux之ARM(IMX6U)裸机汇编LED驱动实验--编译驱动

热门文章

  1. 批处理删除编译产生的多余文件
  2. JS:attachEvent和addEventListener方法
  3. 关于ARM Cortex系列产品
  4. 线性回归——lasso回归和岭回归(ridge regression)
  5. 项目托管到Github
  6. 设备像素,设备独立像素,CSS像素
  7. 获得WebApi用Post方法获得新增数据的信息
  8. 改变 PropertyGrid 控件的编辑风格(2)——编辑多行文本
  9. 自我理解:const char*, char const* and char *const
  10. oracle学习笔记(二)------函数