美文网首页程序员程序园
【JAVA UT】15、mock与stub的比较

【JAVA UT】15、mock与stub的比较

作者: 码术张 | 来源:发表于2019-04-25 14:02 被阅读2次

文|码术张

本节通过比较stub与mock,加深对stub、mock的认识。

1、相同点

都是在ut中消除依赖的一种方式。

如前面两节,针对同一个类,在ut中分别使用了stub和mock,最后达到同样的测试效果。

2、不同点

2.1 实现方式不同

stub需要手动实现被依赖项,而mock则是使用mock framework。

在《什么是stub》中,依赖是NameLoader,ut中实际使用的是:

NameLoader的手动实现版本NameLoaderStub。

在《mock--消除依赖的另一种方法》中,同样的依赖NameLoader,ut中实际使用的是:

Mockito框架中的mock方法实现的版本nameLoader:

nameLoader = mock(NameLoader.class);

2.2 测试类型不同

使用stub,只能做状态测试;使用mock,只可以做行为测试。

2.2.1 状态测试

什么是状态测试(state verification)?

即检查行为的结果。

例如,下面代码片段:

        boolean result = nameChecker.nameIsOnServer(ladp_addr, name);
        
        assertTrue(result)

assertTrue(result)的作用是验证result是否为true。result是行为nameIsOnServer的结果。

2.2.2 行为测试

什么是行为测试(behavior verification)?

即验证是否存在某个行为。

举例如下。

NameChecker类中有一个方法nameIsOnServer。此方法用于检查一个名字是不是记录在服务器中。addr是服务器地址,name是被检查的名字。

如果name不在服务器中,则返回false,并且报警。

public class NameChecker {
    private NameLoader nameLoader;
    private Alarmer alarmer;
    
    public NameChecker(NameLoader loader_in, Alarmer alarmer_in) {
        nameLoader = loader_in;
        alarmer = alarmer_in;
    }

    public boolean nameIsOnServer(String addr, String name) {
        List nameList = nameLoader.download(addr);
        if (nameList.contains(name)) {
            return true;
        }
        alarmer.reportAlarm("name is not in server.");
        return false;
    }
}

报警方式是调用Alarmer的reportAlarm方法。reportAlarm方法的具体实现,不用关心。

public class Alarmer {

    public void reportAlarm(String text){
        ......
    }
}

现在为NameChecker类写ut。

ut面临两个依赖项NameLoader、Alarmer。

使用mock方法消除这两项依赖。

ut如下:

public class NameCheckerTest {
    private NameChecker nameChecker;
    private NameLoader nameLoader;
    private Alarmer     alarmer;

    @Before
    public void setUp() {
        nameLoader = mock(NameLoader.class);
        alarmer    = mock(Alarmer.class);
        nameChecker = new NameChecker(nameLoader, alarmer);
    }

    @Test
    public void shouldReportAlarm(){
        List<String> nameList = new ArrayList<String>();
        nameList.add("a");
        nameList.add("b");
        when(nameLoader.download(anyString())).thenReturn(nameList);

        String ladp_addr = "ldap://10.56.78.23:636";
        String name = "c";

        boolean result = nameChecker.nameIsOnServer(ladp_addr, name);

        assertFalse(result);
        verify(alarmer, times(1)).reportAlarm(anyString());
    }
}

运行结果如下:


运行结果.png

verify(alarmer, times(1)).reportAlarm(anyString());

这verify语句的意思是,期望alarmer的reportAlarm方法,被调用了一次,参数为string类型。

这里只是验证reportAlarm这一行为是否被调用。而不是验证这一行为的结果如何。这就是行为验证。

参考:

https://www.martinfowler.com/articles/mocksArentStubs.html

相关文章

  • 【JAVA UT】15、mock与stub的比较

    文|码术张 本节通过比较stub与mock,加深对stub、mock的认识。 1、相同点 都是在ut中消除依赖的一...

  • Mock与Stub

    Mock验证行为,Stub验证状态。但需要细分一下场景: 1. 需要test double提供输入时,state也...

  • php单元测试进阶(13)- 核心技术 - mock对象 - 同

    php单元测试进阶(13)- 核心技术 - mock对象 - 同时使用mock和stub 本系列文章主要代码与文字...

  • Dubbo Stub与Mock

    前言 大家好,今天开始给大家分享 — Dubbo 专题之 Dubbo Stub和Mock。在前一个章节中我们介绍了...

  • Mock and Stub

    description: We have a dojo about Mock and Stub.But first...

  • Java单元测试

    概念 Stub和Mock 为什么使用Stub或者Mock? 因为要测试的对象通常会依赖于其他对象,而我们并不需要测...

  • 【JAVA-UT】13、什么是stub

    约翰接到一个任务,为下面这个类写ut。 这个类的功能为检查一个名字是否在服务器上。addr是服务器地址,name是...

  • JAVA-Mock测试框架简记-2017-2-7 18:38:3

    JAVA-常用Mock测试框架 EasyMock 早期比较流行的MocK测试框架 mockito EasyMock...

  • 微服务实战之Mock

    模拟对象 一般都叫 Mock 或 Stub, 两者差不多, 都是模拟被测组件对外依赖的模拟, 存根 stub 就在...

  • Mockito入门

    mock使用 mock主要在单元测试的时候用来模拟外部依赖接口的返回,即method stub的作用。 一般而言,...

网友评论

    本文标题:【JAVA UT】15、mock与stub的比较

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