zoukankan      html  css  js  c++  java
  • stub和mock的实际应用

    当项目做大的时候,分清楚单元测试和集成测试是必要的。在单元测试的阶段,分清楚stub和mock的概念,有助于我们使用最合适的工具,最小的代价实现我们的测试目标和外部依赖之间的关联。

    从概念上说stub是外部依赖的一个简单实现,它暴露出测试所需要的方法,以及需要验证的状态。单元测试的时候,它的这些方法会被调用到,而其内部状态也会发生改变,我们就可以对这个内部状态进行验证。它的理论上,如果我们测试目标如我们期望的那样工作,那么依赖服务的状态必然如我们期望的那样改变。

    相比较而言,mock关心的是调用的行为,它也会为一个接口创建一个对象(无须编码),这个对象它只关心这个对象的输入参数和返回值。mock的可以设定期望的调用行为,并记录实际的调用行为,以便于最后进行验证。它的理论是,如果依赖对象输入输出满足期望,那么我们就能测试我们的目标是否如我们期望的那样工作。与stub不同在于,mock时,我们最终验证的是目标对象的状态,而不是依赖对象的状态。

    举个例子,假设我们有一个Service是计算银行的贷款利息的,AccountService,它有一个方法

    double calculate(total, length,credit_level,ID)

    在这个方法内部,它需要调用BankInfoService来获取利率,资质等信息,进行复杂的运算,并最终为申请人建立一个贷款帐户。

    为了测试AccountService,我们可以实现BankInfoService的stub,并最终验证贷款帐户是否建立。

    另一方面我们也可以实现一个mock,并为所有的方法设定输入,输出的期望(所谓record),然后进行调用(replay),最后我们可以验证两个方面,一是是否所有的方法都被调用,二是最终结果(调用BankInfoService的参数)是否符合期望。

    目前实现stub需要自己编码实现,mock可以有软件支持,mockito用起来不错。实际应用时stub和mock可能会互相转换。如果mock的对象输入参数是一个比较大集合,并且输入输出的映射并不是一个简单的映射关系,那么我们可能需要写很多个mock的expected return。此时用stub可能更合适些。相反的方向,如果stub的方法数不多,并且输入输出都很简单,那么mock方法也可以考虑。当然stub如果有自己的内部状态,mock就不容易取代了。

  • 相关阅读:
    LeetCode "Jump Game"
    LeetCode "Pow(x,n)"
    LeetCode "Reverse Linked List II"
    LeetCode "Unique Binary Search Trees II"
    LeetCode "Combination Sum II"
    LeetCode "Divide Two Integers"
    LeetCode "First Missing Positive"
    LeetCode "Clone Graph"
    LeetCode "Decode Ways"
    LeetCode "Combinations"
  • 原文地址:https://www.cnblogs.com/alphablox/p/2914075.html
Copyright © 2011-2022 走看看