美文网首页
SpringBoot 与 JUnit+Mockito 单元测试

SpringBoot 与 JUnit+Mockito 单元测试

作者: hemiao3000 | 来源:发表于2021-02-18 13:41 被阅读0次

JUnit和Mockito

对于JUnit,这里就不详细介绍了,网上的教程有很多,比如这个这个

下面主要介绍一下Mockito。

什么是mock测试,什么是mock对象?

先来看看下面这个示例:

image.png

从上图可以看出如果我们要对A进行测试,那么就要先把整个依赖树构建出来,也就是BCDE的实例。

一种替代方案就是使用mocks

image.png

从图中可以清晰的看出:

  • mock对象就是在调试期间用来作为真实对象的替代品
  • mock测试就是在测试过程中,对那些不容易构建的对象用一个虚拟对象来代替测试的方法就叫mock测试

模拟的好处是什么?

  • 提前创建测试; TDD(测试驱动开发)
      
    如果你创建了一个Mock那么你就可以在service接口创建之前写Service Tests了,这样你就能在开发过程中把测试添加到你的自动化测试环境中了。换句话说,模拟使你能够使用测试驱动开发。

  • 团队可以并行工作
     
     这类似于上面的那点;为不存在的代码创建测试。但前面讲的是开发人员编写测试程序,这里说的是测试团队来创建。当还没有任何东西要测的时候测试团队如何来创建测试呢?模拟并针对模拟测试!这意味着当service借口需要测试时,实际上QA团队已经有了一套完整的测试组件;没有出现一个团队等待另一个团队完成的情况。这使得模拟的效益型尤为突出了。

  • 你可以创建一个验证或者演示程序。

  • 为无法访问的资源编写测试

这个好处不属于实际效益的一种,而是作为一个必要时的“救生圈”。有没有遇到这样的情况?当你想要测试一个service接口,但service需要经过防火墙访问,防火墙不能为你打开或者你需要认证才能访问。遇到这样情况时,你可以在你能访问的地方使用MockService替代,这就是一个“救生圈”功能。

  • Mock 可以分发给用户

  • 隔离系统

知道什么是mock测试后,那么我们就来认识一下mock框架---Mockito。

Mockito区别于其他模拟框架的地方主要是允许开发者在没有建立“预期”时验证被测系统的行为。

Mockito相关教程:

(与此同时推荐一个东西,SpringOckito, 不过已经2年没更新了。)

mockito入门实例

Maven依赖:

XML 代码

<dependencies>  
  <dependency>  
    <groupId>org.mockito</groupId>  
    <artifactId>mockito-all</artifactId>  
    <version>1.8.5</version>  
    <scope>test</scope>  
  </dependency>  
</dependencies>

首先,需要在@Before注解的setUp()中进行初始化(下面这个是个测试类的基类)

Java代码

public abstract class MockitoBasedTest {
    @Before
    public void setUp() throws Exception {
        // 初始化测试用例类中由Mockito的注解标注的所有模拟对象
        MockitoAnnotations.initMocks(this);
    }
}

Java代码

import static org.mockito.Mockito.*;
import java.util.List;
import org.junit.Assert;
import org.junit.Test;
public class SimpleTest {  

    @Test  
    public void simpleTest(){  

        //创建mock对象,参数可以是类,也可以是接口  
        List<String> list = mock(List.class);  

        //设置方法的预期返回值  
        when(list.get(0)).thenReturn("helloworld");  

        String result = list.get(0);  

        //验证方法调用(是否调用了get(0))  
        verify(list).get(0);  

        //junit测试  
        Assert.assertEquals("helloworld", result);  
    }  
}

创建mock对象不能对final,Anonymous ,primitive类进行mock。

可对方法设定返回异常

Java代码

when(list.get(1)).thenThrow(new RuntimeException("test excpetion"));

stubbing另一种语法(设置预期值的方法),可读性不如前者

Java代码

doReturn("secondhello").when(list).get(1);

没有返回值的void方法与其设定(支持迭代风格,第一次调用donothing,第二次dothrow抛出runtime异常)

Java代码

doNothing().doThrow(new RuntimeException("void exception")).when(list).clear();  
list.clear();  
list.clear();  
verify(list,times(2)).clear();

参数匹配器(Argument Matcher)

Matchers类内加你有很多参数匹配器 anyInt、anyString、anyMap.....Mockito类继承于Matchers,Stubbing时使用内建参数匹配器,下例:

Java代码

@Test  
public void argumentMatcherTest(){  
    List<String> list = mock(List.class);  

    when(list.get(anyInt())).thenReturn("hello","world");  

    String result = list.get(0)+list.get(1);  

    verify(list,times(2)).get(anyInt());  

    Assert.assertEquals("helloworld", result);  
}

需要注意的是:如果使用参数匹配器,那么所有的参数都要使用参数匹配器,不管是stubbing还是verify的时候都一样。

https://zhuanlan.zhihu.com/p/21444517

相关文章

网友评论

      本文标题:SpringBoot 与 JUnit+Mockito 单元测试

      本文链接:https://www.haomeiwen.com/subject/zeigxltx.html