JAVA中单元测试的常用方式(小结)

 更新时间:2019年06月24日 09:51:55   作者:空无  
这篇文章主要介绍了JAVA中单元测试的常用方式(小结),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

什么是单元测试

单元测试(英语:Unit Testing)又称为模块测试, 是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作。程序单元是应用的最小可测试部件。在过程化编程中,一个单元就是单个程序、函数、过程等;对于面向对象编程,最小单元就是方法,包括基类(超类)、抽象类、或者派生类(子类)中的方法。

通常来说,程序员每修改一次程序就会进行最少一次单元测试,在编写程序的过程中前后很可能要进行多次单元测试,以证实程序达到软件规格书要求的工作目标,没有程序错误;虽然单元测试不是什么必须的,但也不坏,这牵涉到项目管理的政策决定。

单元测试的优点

优质的单元测试可以保障开发质量和程序的鲁棒性。在大多数互联网企业中开发工程师在研发过程中都会频繁地执行测试用例,运行失败的单测能帮助我们快速排查和定位问题 使问题在被带到线上之前完成修复。正如软件工程界的一条金科玉律----越早发现的缺陷,其修复成本越低。一流的测试能发现未发生的故障;二流的测试能快速定位故障的发生点;三流的测试则疲于奔命,一直跟在故障后面进行功能回归。
JAVA中常用的单元测试工具

JUnit/JUnit5

https://junit.org/junit5/

junit是老牌测试框架了,也是目前引用最广泛的一个框架。当前已经更新到Junit5,功能更强大。

class StandardTests {

  @BeforeAll
  static void initAll() {
  }

  @BeforeEach
  void init() {
  }

  @Test
  void succeedingTest() {
  }

  @Test
  void failingTest() {
    fail("a failing test");
  }

  @Test
  @Disabled("for demonstration purposes")
  void skippedTest() {
    // not executed
  }

  @Test
  void abortedTest() {
    assumeTrue("abc".contains("Z"));
    fail("test should have been aborted");
  }

  @AfterEach
  void tearDown() {
  }

  @AfterAll
  static void tearDownAll() {
  }

}

assertj

https://assertj.github.io/doc/

一个功能强悍的断言工具,支持各种断言方式

// entry point for all assertThat methods and utility methods (e.g. entry)
import static org.assertj.core.api.Assertions.*;

// basic assertions
assertThat(frodo.getName()).isEqualTo("Frodo");
assertThat(frodo).isNotEqualTo(sauron);

// chaining string specific assertions
assertThat(frodo.getName()).startsWith("Fro")
              .endsWith("do")
              .isEqualToIgnoringCase("frodo");

// collection specific assertions (there are plenty more)
// in the examples below fellowshipOfTheRing is a List<TolkienCharacter>
assertThat(fellowshipOfTheRing).hasSize(9)
                .contains(frodo, sam)
                .doesNotContain(sauron);

// as() is used to describe the test and will be shown before the error message
assertThat(frodo.getAge()).as("check %s's age", frodo.getName()).isEqualTo(33);

// Java 8 exception assertion, standard style ...
assertThatThrownBy(() -> { throw new Exception("boom!"); }).hasMessage("boom!");
// ... or BDD style
Throwable thrown = catchThrowable(() -> { throw new Exception("boom!"); });
assertThat(thrown).hasMessageContaining("boom");

// using the 'extracting' feature to check fellowshipOfTheRing character's names (Java 7)
assertThat(fellowshipOfTheRing).extracting("name")
                .contains("Boromir", "Gandalf", "Frodo", "Legolas")
// same thing using a Java 8 method reference
assertThat(fellowshipOfTheRing).extracting(TolkienCharacter::getName)
                .doesNotContain("Sauron", "Elrond");

// extracting multiple values at once grouped in tuples (Java 7)
assertThat(fellowshipOfTheRing).extracting("name", "age", "race.name")
                .contains(tuple("Boromir", 37, "Man"),
                     tuple("Sam", 38, "Hobbit"),
                     tuple("Legolas", 1000, "Elf"));

// filtering a collection before asserting in Java 7 ... 
assertThat(fellowshipOfTheRing).filteredOn("race", HOBBIT)
                .containsOnly(sam, frodo, pippin, merry);
// ... or in Java 8
assertThat(fellowshipOfTheRing).filteredOn(character -> character.getName().contains("o"))
                .containsOnly(aragorn, frodo, legolas, boromir);

// combining filtering and extraction (yes we can)
assertThat(fellowshipOfTheRing).filteredOn(character -> character.getName().contains("o"))
                .containsOnly(aragorn, frodo, legolas, boromir)
                .extracting(character -> character.getRace().getName())
                .contains("Hobbit", "Elf", "Man");

// and many more assertions: iterable, stream, array, map, dates (java 7 and 8), path, file, numbers, predicate, optional ...

Mockito

https://site.mockito.org/

一个单元测试中的Mock工具,可以很灵活的创建对象,配合单元测试。

// You can mock concrete classes and interfaces
TrainSeats seats = mock(TrainSeats.class);

// stubbing appears before the actual execution
when(seats.book(Seat.near(WINDOW).in(FIRST_CLASS))).thenReturn(BOOKED);

// the following prints "BOOKED"
System.out.println(seats.book(Seat.near(WINDOW).in(FIRST_CLASS)));

// the following prints "null" because 
// .book(Seat.near(AISLE).in(FIRST_CLASS))) was not stubbed
System.out.println(seats.book(Seat.near(AISLE).in(FIRST_CLASS)));

// the following verification passes because 
// .book(Seat.near(WINDOW).in(FIRST_CLASS)) has been invoked
verify(seats).book(Seat.near(WINDOW).in(FIRST_CLASS));

// the following verification fails because 
// .book(Seat.in(SECOND_CLASS)) has not been invoked
verify(seats).book(Seat.in(SECOND_CLASS));

其他

对于业务代码,有时单元测试并不方便,因为每次启动成本过高。可以使用适当的单元测试方式,比如可以提供一个测试接口,利用IDE的热部署功能实现不重启及时修改代码。

但是对于非业务性代码,进行单元测试时非常有必要的,可以更早的发现代码中的问题,同时也可以检验程序的解耦性。

良好的代码设计在单元测试时会更方便,反之紧耦合的设计会给单元测试带来很大的困扰。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • java中的arrays.sort()代码详解

    java中的arrays.sort()代码详解

    这篇文章主要介绍了Java中的Arrays.sort()代码详解,涉及Arrays.sort()简单示例,策略模式,”super”的使用等相关内容,具有一定借鉴价值,需要的朋友可以参考下。
    2017-12-12
  • Java之TreeSet和TreeMap的两种排序方式解读

    Java之TreeSet和TreeMap的两种排序方式解读

    这篇文章主要介绍了Java之TreeSet和TreeMap的两种排序方式解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • Java中枚举的实现与应用详解

    Java中枚举的实现与应用详解

    这篇文章主要介绍了Java中枚举的实现与应用详解,EnumTest中还有一个VALUES数组,里面存储着所有的枚举实例,调用values方法时返回VALUES数组的clone,需要的朋友可以参考下
    2023-12-12
  • Installij IDEA install或clean项目的使用

    Installij IDEA install或clean项目的使用

    这篇文章主要介绍了Installij IDEA install或clean项目的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • java 中继承和多态详细介绍

    java 中继承和多态详细介绍

    这篇文章主要介绍了java 中继承和多态详细介绍的相关资料,需要的朋友可以参考下
    2017-05-05
  • Eclipse中实现JS代码提示功能(图文教程)

    Eclipse中实现JS代码提示功能(图文教程)

    本文通过图文并茂的形式给大家介绍了Eclipse中实现JS代码提示功能,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2017-11-11
  • CMD运行Intellij Idea编译后的class文件操作

    CMD运行Intellij Idea编译后的class文件操作

    这篇文章主要介绍了CMD运行Intellij Idea编译后的class文件操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • javaweb学习总结——使用JDBC处理MySQL大数据

    javaweb学习总结——使用JDBC处理MySQL大数据

    本篇文章主要介绍了JDBC处理MySQL大数据,有时是需要用程序把大文本或二进制数据直接保存到数据库中进行储存的,非常具有实用价值,需要的朋友可以参考下。
    2016-11-11
  • 深入详解java高并发热点数据更新

    深入详解java高并发热点数据更新

    这篇文章主要为大家深入介绍了java高并发热点数据更新详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • SpringBoot yaml语法与数据读取操作详解

    SpringBoot yaml语法与数据读取操作详解

    YAML 是 “YAML Ain’t Markup Language”(YAML 不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:“Yet Another Markup Language”(仍是一种标记语言),本文给大家介绍的非常详细,需要的朋友可以参考下
    2022-07-07

最新评论