目录

  • 目录
  • 测试接口和默认方法
    • 定义接口
    • 测试案例
  • 接口契约
    • 接口定义
    • 测试类
  • 系列导航

测试接口和默认方法

JUnit Jupiter允许在接口默认方法上声明@Test、@RepeatedTest、@ParameterizedTest、@TestFactory、@TestTemplate、@BeforeEach和@AfterEach。
如果测试接口或测试类被@TestInstance(Lifecycle.PER_CLASS)注释,
则@BeforeAll和@AfterAll可以在测试接口中的静态方法上声明,也可以在接口默认方法上声明。

这里有一些例子。

定义接口

  • TestLifecycleLogger.java
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.api.TestInstance;import java.util.logging.Logger;@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public interface TestLifecycleLogger {static final Logger LOG = Logger.getLogger(TestLifecycleLogger.class.getName());@BeforeAlldefault void beforeAllTests() {LOG.info("Before all tests");}@AfterAlldefault void afterAllTests() {LOG.info("After all tests");}@BeforeEachdefault void beforeEachTest(TestInfo testInfo) {LOG.info(() -> String.format("About to execute [%s]",testInfo.getDisplayName()));}@AfterEachdefault void afterEachTest(TestInfo testInfo) {LOG.info(() -> String.format("Finished executing [%s]",testInfo.getDisplayName()));}
}
  • TestInterfaceDynamicTestsDemo.java
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;import java.util.Arrays;
import java.util.Collection;import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.DynamicTest.dynamicTest;public interface TestInterfaceDynamicTestsDemo {@TestFactorydefault Collection<DynamicTest> dynamicTestsFromCollection() {return Arrays.asList(dynamicTest("1st dynamic test in test interface", () -> assertTrue(true)),dynamicTest("2nd dynamic test in test interface", () -> assertEquals(4, 2 * 2)));}
}

可以在测试接口上声明 @ExtendWith@Tag,以便实现该接口的类自动继承其标记和扩展。
查看测试执行前后对 TimingExtension 源代码的回调。

  • TimeExecutionLogger.java
@Tag("timed")
@ExtendWith(TimingExtension.class)
interface TimeExecutionLogger {
}
  • TimingExtension.java
import java.lang.reflect.Method;
import java.util.logging.Logger;import org.junit.jupiter.api.extension.AfterTestExecutionCallback;
import org.junit.jupiter.api.extension.BeforeTestExecutionCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ExtensionContext.Namespace;
import org.junit.jupiter.api.extension.ExtensionContext.Store;public class TimingExtension implements BeforeTestExecutionCallback, AfterTestExecutionCallback {private static final Logger logger = Logger.getLogger(TimingExtension.class.getName());private static final String START_TIME = "start time";@Overridepublic void beforeTestExecution(ExtensionContext context) throws Exception {getStore(context).put(START_TIME, System.currentTimeMillis());}@Overridepublic void afterTestExecution(ExtensionContext context) throws Exception {Method testMethod = context.getRequiredTestMethod();long startTime = getStore(context).remove(START_TIME, long.class);long duration = System.currentTimeMillis() - startTime;logger.info(() -> String.format("Method [%s] took %s ms.", testMethod.getName(), duration));}private Store getStore(ExtensionContext context) {return context.getStore(Namespace.create(getClass(), context.getRequiredTestMethod()));}
}

测试案例

  • TestInterfaceDemo.java
import org.junit.jupiter.api.Test;import static org.junit.jupiter.api.Assertions.assertEquals;class TestInterfaceDemo implements TestLifecycleLogger,TimeExecutionLogger, TestInterfaceDynamicTestsDemo {@Testvoid isEqualValue() {assertEquals(1, 1, "is always equal");}
}

日志如下:

Jun 25, 2018 6:18:43 PM com.github.houbb.jdk.junit5.interfaces.TestLifecycleLogger beforeAllTests
信息: Before all tests
Jun 25, 2018 6:18:43 PM com.github.houbb.jdk.junit5.interfaces.TestLifecycleLogger beforeEachTest
信息: About to execute [isEqualValue()]
Jun 25, 2018 6:18:43 PM com.github.houbb.jdk.junit5.interfaces.TimingExtension afterTestExecution
信息: Method [isEqualValue] took 4 ms.
Jun 25, 2018 6:18:43 PM com.github.houbb.jdk.junit5.interfaces.TestLifecycleLogger afterEachTest
信息: Finished executing [isEqualValue()]
Jun 25, 2018 6:18:43 PM com.github.houbb.jdk.junit5.interfaces.TestLifecycleLogger afterAllTests
信息: After all tests

接口契约

这个特性的另一个可能的应用是为接口契约编写测试。

例如,您可以为对象的实现方式编写测试。Object.equals 的或 Comparable.compareTo 的。

接口定义

  • Testable.java
public interface Testable<T> {T createValue();}
  • EqualsContract.java
import org.junit.jupiter.api.Test;import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;public interface EqualsContract<T> extends Testable<T> {T createNotEqualValue();@Testdefault void valueEqualsItself() {T value = createValue();assertEquals(value, value);}@Testdefault void valueDoesNotEqualNull() {T value = createValue();assertFalse(value.equals(null));}@Testdefault void valueDoesNotEqualDifferentValue() {T value = createValue();T differentValue = createNotEqualValue();assertNotEquals(value, differentValue);assertNotEquals(differentValue, value);}
}
  • ComparableContract.java
import org.junit.jupiter.api.Test;import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;public interface ComparableContract<T extends Comparable<T>> extends Testable<T> {T createSmallerValue();@Testdefault void returnsZeroWhenComparedToItself() {T value = createValue();assertEquals(0, value.compareTo(value));}@Testdefault void returnsPositiveNumberComparedToSmallerValue() {T value = createValue();T smallerValue = createSmallerValue();assertTrue(value.compareTo(smallerValue) > 0);}@Testdefault void returnsNegativeNumberComparedToSmallerValue() {T value = createValue();T smallerValue = createSmallerValue();assertTrue(smallerValue.compareTo(value) < 0);}
}

测试类

在您的测试类中,您可以实现这两个契约接口,从而继承相应的测试。当然,您必须实现抽象方法。

  • StringTest.java
public class StringTestimplements ComparableContract<String>, EqualsContract<String>{@Overridepublic String createValue() {return "foo";}@Overridepublic String createSmallerValue() {return "bar"; // 'b' < 'f' in "foo"}@Overridepublic String createNotEqualValue() {return "baz";}
}

系列导航

系列导航

junit5 入门系列教程-13-junit5 测试接口及默认方法相关推荐

  1. junit5 入门系列教程-02-junit5 注解详解

    目录 目录 Junit5 注解 @Test @ParameterizedTest @RepeatedTest @TestFactory @TestInstance @TestTemplate @Dis ...

  2. junit5 入门系列教程-17-junit5 动态测试(DynamicTest)

    目录 目录 动态测试 生命周期 测试案例 系列导航 动态测试 在标注中描述的JUnit Jupiter中的标准@Test注释与JUnit 4中的@Test注释非常相似.两者都描述了实现测试用例的方法. ...

  3. Provisioning Services 7.8 入门系列教程之十三 使用 Boot Device Management(BDM)

    续Provisioning Services 7.8 入门系列教程之十二 实现高可用性 可以使用 Boot Device Management 实用程序将 IP 和引导信息(引导设备)交付给目标设备, ...

  4. Provisioning Services 7.8 入门系列教程之十四 UEFI支持和BOOTPTAB 编辑器

     续Provisioning Services 7.8 入门系列教程之十三 使用 Boot Device Management(BDM) UEFI,全称Unified Extensible Firmw ...

  5. graphviz 画决策树_数据挖掘入门系列教程(四)之基于scikit-lean决策树处理Iris

    数据挖掘入门系列教程(四)之基于scikit-lean决策树处理Iris 加载数据集 数据特征 训练 随机森林 调参工程师 结尾 数据挖掘入门系列教程(四)之基于scikit-lean决策树处理Iri ...

  6. Provisioning Services 7.8 入门系列教程之十一 通过版本控制自动更新虚拟磁盘

    续Provisioning Services 7.8 入门系列教程之十 通过类自动更新虚拟磁盘 从前两的两种更新方式可以看出,它们有一个共同的特点,即需要产生(复制)完成的虚拟磁盘副本,然后进行相关的 ...

  7. html5游戏制作入门系列教程(八)

    今天,我已经准备了一个新的游戏 – SkyWalker.基本上 – 这是用飞飞行模拟射击类游戏.我们的目标到达终点线.这个游戏还有其它一些特点,例如使用飞机运动动画和爆炸动画,多按键处理(例如同时移动 ...

  8. Provisioning Services 7.8 入门系列教程之五 使用Provisioning Services控制台

    续Provisioning Services 7.8 入门系列教程之四 目标设备安装 使用 Provisioning Services 控制台可管理 Provisioning Services 场中的 ...

  9. STM32 基础系列教程 13 – ADC DMA

    前言 学习stm32 adc模数转换接口使用,学会用STM32对模拟信号时行采样,通过DMA方式得到ADC结果. 示例详解 基于硬件平台: STM32F10C8T6最小系统板, MCU 的型号是 ST ...

  10. html5游戏制作入门系列教程(七)

    我们继续这一系列文章,使用HTML5的canvas组件进行游戏开发.我们将要更新完善我们的第4课html5游戏制作入门系列教程(四)的游戏实例,并增加了火球,敌人和碰撞检测等功能模块.所以,现在我们的 ...

最新文章

  1. 水晶报表Crystal 语法 实用字段编辑
  2. 零基础自学python看什么书-零基础Python入门看哪本书好?这里有答案
  3. 蓝桥杯2015初赛-三羊献瑞-枚举
  4. 【Fudan DISC】一种无监督下利用多模态文档结构信息帮助图片-句子匹配的采样方法...
  5. 股票成本价买入价计算器 V1.3
  6. cef调用本地html,在CefSharp中使用本地构建的网页(Working with locally built web page in CefSharp)...
  7. cad2018安装教程_安装CAD后,我首先干了这些事!
  8. var that =this的用法详解
  9. 眼见不一定为实,电阻、电容和电感的实际等效模型
  10. 投稿时文章脚注数字如何去掉
  11. 标准盒子模型和IE盒子模型
  12. PV,UV,VV,IP
  13. CSS 成长之路(六)顶线、中线、基线、底线与行距
  14. u2020 华为_顶级锐龙标压U加持!华为MateBook 13 2020锐龙版评测:轻薄本稳压40W
  15. Android4.4 状态栏WiFi图标显示流程
  16. JavaScript Errors 指南
  17. 如何分析PARSEC源码
  18. 13:js逆向-登录加密(aes加密)
  19. 表白代码c语言,C语言告白代码,一闪一闪亮晶晶~
  20. CRC常用参数模型及C#代码实现

热门文章

  1. oppoR9s计算机使用方法,oppor9s怎么进入Recovery模式
  2. 翻遍知乎1000多个高赞回答,我找到了这7本计算机圣经
  3. 打印2018年的日历
  4. java 中怎么打印一个日历_日历打印用java实现
  5. 微信小程序语音播放功能的实现
  6. U1C3 介绍SketchEngine和Web语料库研究
  7. 【正点原子Linux连载】第六十五章 Linux 音频驱动实验 -摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.0
  8. MQ消息队列的12点核心原理总结
  9. java计算机毕业设计家庭安防系统MyBatis+系统+LW文档+源码+调试部署
  10. 【C++】快速幂与矩阵快速幂