学习 Java JUnit 单元测试一篇文章就够了

Posted 南淮北安

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习 Java JUnit 单元测试一篇文章就够了相关的知识,希望对你有一定的参考价值。

一、测试的类型

(1)单元测试(Unit test):单元测试关注单一的类. 它们存在的目的是检查这个类中的代码是否按照期望正确运行.

(2)集成测试(Integration test):顾名思义, 集成测试是检查开发的模块和其他模块整合时是否正常工作.
虽然集成测试的代码影响范围比单元测试要广, 但是集成测试和单元测试一样, 也是针对于开发者而言的.

(3)端到端测试(End-to-End test):端到端测试是将整个系统作为一个整体, 然后从用户的角度进行测试的.
端到端测试的目的是测试系统在实际使用的是否正常的, 因此通常来说是不需要测试替身的(Test Double)

二、单元测试

单元测试的目的: 测试当前所写的代码是否是正确的, 例如输入一组数据, 会输出期望的数据; 输入错误数据, 会产生错误异常等.

在单元测试中, 我们需要保证被测系统是独立的(SUT 没有任何的 DOC), 即当被测系统通过测试时, 那么它在任何环境下都是能够正常工作的.

编写单元测试时, 仅仅需要关注单个类就可以了. 而不需要关注例如数据库服务, Web 服务等组件.

(1)被测系统:被测系统(System under test, SUT)表示正在被测试的系统, 目的是测试系统能否正确操作.根据测试类型的不同, SUT 指代的内容也不同, 例如 SUT 可以是一个类甚至是一整个系统.

(2)测试依赖组件(DOC):被测系统所依赖的组件, 例如进程 UserService 的单元测试时, UserService 会依赖 UserDao, 因此 UserDao 就是 DOC.

(3)测试替身(Test Double):一个实际的系统会依赖多个外部对象, 但是在进行单元测试时, 我们会用一些功能较为简单的并且其行为和实际对象类似的假对象来作为 SUT 的依赖对象, 以此来降低单元测试的复杂性和可实现性. 在这里, 这些假对象就被称为 测试替身(Test Double).

测试替身有如下 5 种类型:

  • Test stub, 为 SUT 提供数据的假对象.
    我们举一个例子来展示什么是 Test stub.
    假设我们的一个模块需要从 HTTP 接口中获取商品价格数据, 这个获取数据的接口被封装为 getPrice 方法. 在对这个模块进行测试时, 我们显然不太可能专门开一个 HTTP 服务器来提供此接口, 而是提供一个带有 getPrice 方法的假对象, 从这个假对象中获取数据.
    在这个例子中, 提供数据的假对象就叫做 Test stub.
  • Fake object
    实现了简单功能的一个假对象. Fake object 和 Test stub 的主要区别就是 Test stub 侧重于用于提供数据的假对象, 而 Fake object 没有这层含义.
    使用 Fake object 的最主要的原因就是在测试时某些组件不可用或运行速度太慢, 因而使用 Fake object 来代替它们.
  • Mock object
    用于模拟实际的对象, 并且能够校验对这个 Mock object 的方法调用是否符合预期.
    实际上, Mock object 是 Test stub 或 Fake object 一种, 但是 Mock object 有 Test stub/Fake object 没有的特性, Mock object 可以很灵活地配置所调用的方法所产生的行为, 并且它可以追踪方法调用, 例如一个 Mock Object 方法调用时传递了哪些参数, 方法调用了几次等.
  • Dummy object: 在测试中并不使用的, 但是为了测试代码能够正常编译/运行而添加的对象. 例如我们调用一个 Test Double 对象的一个方法, 这个方法需要传递几个参数, 但是其中某个参数无论是什么值都不会影响测试的结果, 那么这个参数就是一个 Dummy object.
    Dummy object 可以是一个空引用, 一个空对象或者是一个常量等.
    简单的说, Dummy object 就是那些没有使用到的, 仅仅是为了填充参数列表的对象.
  • Test Spy
    可以包装一个真实的 Java 对象, 并返回一个包装后的新对象. 若没有特别配置的话, 对这个新对象的所有方法调用, 都会委派给实际的 Java 对象.

mock 和 spy 的区别是: mock 是无中生有地生出一个完全虚拟的对象, 它的所有方法都是虚拟的;

而 spy 是在现有类的基础上包装了一个对象, 即如果我们没有重写 spy 的方法, 那么这些方法的实现其实都是调用的被包装的对象的方法.

单元测试在开发中占据很重要的地位,它能发现问题,提高效率,在java中应用最广泛的单元测试框架就是Junit,它被集成在了多个框架或者工具中,例如IDEA、Spring等。

三、Junit 简单使用

首先添加依赖:

		<dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <!--限制只能在测试编译时才可以使用-->
            <scope>test</scope>
        </dependency>

接着编写测试套件:

public class TestJunit {
    @Test
    public void testingCrunchifyAddition() {
        assertEquals("Here is test for Addition Result: ", 30, addition(27, 3));
    }

    @Test
    public void testingHelloWorld() {
        assertEquals("Here is test for Hello World String: ", "Hello + World", helloWorld());
    }

    public int addition(int x, int y) {
        return x + y;
    }

    public String helloWorld() {
        String helloWorld = "Hello +" + " World";
        return helloWorld;
    }
}

随后使用测试用例:

public class App {
    public static void main(String[] args) {
        Result result = JUnitCore.runClasses(TestJunit.class);
        for (Failure failure : result.getFailures()) {
            System.out.println(failure.toString());
        }
        if (result.wasSuccessful()) {
            System.out.println("Both Tests finished successfully...");
        }
    }
}

四、常用注解


(1)@Test 注解:被@Test 标注的方法就是执行测试用例的测试方法, 例如:

public class TestJunit {
    @Test
    public void  myTest() {
        assertEquals("Here is test for Addition Result: ", 30, addition(27, 3));
    }
}

方法myTest 被注解@Test 标注, 表示这个方法是一个测试方法, 当运行测试用例时, 会自动调用这个方法

(2)@BeforeClass , @AfterClass, @Before, @After:使用@BeforeClass 和 @AfterClass 两个注解标注的方法会在所有测试方法执行前后各执行一次
使用@Before 和 @After 两个注解标注的方法会在每个测试方法执行前后都执行一次.

(3)TestSuite:如果有多个测试类, 可以合并成一个测试套件进行测试, 运行一个 Test Suite, 那么就会运行在这个 Test Suite 中的所用的测试.

import org.junit.runner.RunWith;  
import org.junit.runners.Suite;  
import org.junit.runners.Suite.SuiteClasses;  
  
@RunWith( Suite.class )  
@SuiteClasses( { JUnitTest1.class, JUnitTest2.class } )  
public class AllTests {

}

在这个例子中, 我们定义了一个 Test Suite, 这个 Test Suite 包含了两个测试类: JUnitTest1 和 JUnitTest2, 因此运行 这个 Test Suite 时, 就会自动运行这两个测试类了.

五、在 IntelliJ IDEA 中使用 JUnit 4

如果已经存在test 目录

则可以直接在要测试的类名上,alt+enter 就可以自动生成测试类


然后即可测试

【参考】

【1】https://www.jianshu.com/p/a3fa5d208c93
【2】https://blog.csdn.net/fulishafulisha/article/details/80158392
【3】https://segmentfault.com/a/1190000006731125
【4】https://blog.csdn.net/gentlezuo/article/details/108160864
【5】https://baijiahao.baidu.com/s?id=1647361249282882030&wfr=spider&for=pc

以上是关于学习 Java JUnit 单元测试一篇文章就够了的主要内容,如果未能解决你的问题,请参考以下文章

学习单元测试常用的断言 assertTrue 和 assertEquals 一篇文章就够了

高效编程SpringMVC框架如何与Junit整合,看这个就够了

高效编程SpringMVC框架如何与Junit整合,看这个就够了

Java 中 Stream 流学习一篇文章就够了

java分布式开发电脑配置,看这一篇就够了!

JUnitJava 单元测试框架 | 学习笔记