前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >spock测试桩mock和stub的区别及使用场景

spock测试桩mock和stub的区别及使用场景

作者头像
yawn
发布2019-09-12 11:02:34
3.8K0
发布2019-09-12 11:02:34
举报
spock测试桩mock和stub的区别及使用场景插图
spock测试桩mock和stub的区别及使用场景插图

如图,有如上的方法调用关系(模块依赖关系):A调用B和E方法,B调用C和D方法。

在使用spock进行单元测试时,有如下情景,分别可使用stub和mock。

使用stub测试桩

如果我们需要测试A方法,但是E方法目前还没办法调用,或者还没开发完成。这种场景下,就可以使用stub测试桩。stub测试桩可以给E方法模拟一个或多个假的返回值,我们测试时只需要调用stub对象的E方法即可,调用后的返回值是我们在生成stub对象时指定的。如下:

    def "Stub 测试桩"() {
        given: "构造测试桩"
        CalculateInterface calculateService = Stub(CalculateInterface)
        calculateService.plusPlus(_) >> 1

        when:
        int x = calculateService.plusPlus(12)
        int y = calculateService.plusPlus(3)

        then:
        x == 1
        y == 1
    }

上面代码中,calculateService.plusPlus(_) >> 1 给一个并未实现的plusPlus()方法指定了返回值为1,测试代码就可以直接调用这个方法了。

其中这个语句的常用格式有:

subscriber.receive(_) >> "ok"
|          |       |     |
|          |       |     生成返回值
|          |       参数
|          方法
对象

生成返回值:

// 不同参数生成不同的返回值
subscriber.receive("message1") >> "ok"
subscriber.receive("message2") >> "fail" 
// 生成多个返回值
subscriber.receive(_) >>> ["ok", "error", "error", "ok"]

通过计算生成返回值

这种方式,生成返回值的格式时一个闭包

// 1.使用方法参数计算
subscriber.receive(_) >> { args -> args[0].size() > 3 ? "ok" : "fail" }
// 2. 使用其他参数
subscriber.receive(_) >> { String message -> message.size() > 3 ? "ok" : "fail" }

如果想调用方法抛出异常

subscriber.receive(_) >> { throw new InternalError("ouch") }

链式生成返回值

subscriber.receive(_) >>> ["ok", "fail", "ok"] >> { throw new InternalError() } >> "ok"

上面代码中,方法被调用的前三次分别返回 “ok”, “fail”, “ok”,第四次会抛出异常,第五次及以后调用,会返回“ok”。

以上是spock中stub测试桩的使用场景,总结为一句就是: stub测试桩给被调用者( 方法/模块)制造假的返回值,以便不影响调用者的测试。

使用mock测试桩

mock测试桩就是模拟一个测试的结果。如下图,A类调用类B和C类的某个方法:

spock测试桩mock和stub的区别及使用场景插图(1)
spock测试桩mock和stub的区别及使用场景插图(1)

如果要测试A的方法,但是我们没办法调用B来检测结果,就可以使用mock测试桩,生成一个B的mock对象。检验结果时,可以使用B的mock对象替代B。这个结果一般是B和C方法的调用或者状态的改变。

    def subscriber = Mock(Subscriber)   // 1. 创建一个mock对象

    def "should send messages subscriber"() {
        when:
        publisher.send("hello")         // 2. publisher 发送一个“hello”
        then:
        1 * subscriber.receive("hello") // 3. subscriber 接收到一个“hello”
        1 * subscriber.messageCount == 1
    }

对于mock对象的断言请参考: http://jvm123.com/2019/09/spock-ce-shi-zhuang-2.html

以上是spock中mock测试桩的使用场景,总结为一句就是: mock测试桩给被测试方法模拟一个预期的效果

mock和stub测试桩的对比

mock测试桩用于检测结果

stub测试桩用于提供测试的条件。

本文来自java技术分享站(jvm123.com)http://jvm123.com/2019/09/spock-ce-shi-zhuang-3.html

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用stub测试桩
    • 生成返回值:
      • 通过计算生成返回值
        • 如果想调用方法抛出异常
          • 链式生成返回值
          • 使用mock测试桩
          • mock和stub测试桩的对比
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档