zoukankan      html  css  js  c++  java
  • Spock集成入门

    本文基于SpringBoot

    在pom.xml添加Spock依赖

            <!-- test -->
            <dependency>
                <groupId>org.codehaus.groovy</groupId>
                <artifactId>groovy-all</artifactId>
                <version>2.4.12</version>
            </dependency>
    
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
    
            <dependency>
            <groupId>org.spockframework</groupId>
            <artifactId>spock-core</artifactId>
            <version>1.1-groovy-2.4</version>
            <scope>test</scope>
            </dependency>

    新建Sum.java

    1 public class Sum {
    2     public int sum(int a, int b) {
    3         return a + b;
    4     }
    5 }

    新建groovy测试脚本SpockSpecification.groovy

      1 package com.test.bookup
      2 
      3 import com.example.demo.Sum
      4 import spock.lang.Specification
      5 import spock.lang.Unroll;
      6 
      7 /**
      8  * Created by hande on 2018/7/18.
      9  */
     10 class SpockSpecification extends  Specification{
     11 
     12     // 调用外部类测试
     13     def sum = new Sum();
     14     def "get sum"(){
     15         expect:
     16         sum.sum(1,1) == 2
     17     }
     18 
     19     // Where Blocks 简单大小比较函数测试
     20     def "get max num"(){
     21         expect:
     22           Math.max(a,b) == c
     23 
     24         where:
     25           a|b|c
     26           1|2|2
     27           1|2|2
     28           2|3|3
     29     }
     30 
     31     def "get min num"(){
     32         expect:
     33         Math.min(a,b) == c
     34 
     35         where:
     36         a|b|c
     37         1|2|1
     38         1|2|1
     39         2|3|2
     40     }
     41 
     42     // 上述例子实际会跑三次测试,相当于在for循环中执行三次测试,如果在方法前声明@Unroll,则会当成三个方法运行。
     43     @Unroll
     44     def "@Unroll test"(){
     45         expect:
     46         Math.min(a,b) == c
     47 
     48         where:
     49         a|b|c
     50         1|2|1
     51         1|2|1
     52         2|3|2
     53     }
     54 
     55     // where block另外两种数据定义方法
     56     def "where block data init method"(){
     57         expect:
     58             Math.max(a,b) == c
     59 
     60         where:
     61             a|_
     62             3|_
     63             7|_
     64             0|_
     65 
     66             b<<[5,0,0]
     67 
     68             c=a>b?a:b
     69     }
     70 
     71 
     72 
     73     // When and Then Blocks
     74     def "When and Then Blocks"(){
     75         setup:
     76           def stack = new Stack();
     77           def em = "push me";
     78 
     79         when:
     80           stack.push(em);
     81 
     82         then:
     83           !stack.empty();
     84           stack.size() == 1;
     85           stack.peek() == em;
     86     }
     87 
     88 
     89 
     90     // mock应用
     91     Publisher publisher = new Publisher()
     92     Subscriber subscriber = Mock()
     93     Subscriber subscriber2 = Mock()
     94 
     95     def setup() {
     96         publisher.subscribers.add(subscriber)
     97         publisher.subscribers.add(subscriber2)
     98     }
     99 
    100     def"should send messages to all subscribers"(){
    101         when:
    102         publisher.send("hello")
    103 
    104         then:
    105         1*subscriber.receive("hello")
    106         1*subscriber2.receive("hello")
    107     }
    108     // 上面的例子里验证了:在publisher调用send时,两个subscriber都应该被调用一次receive(“hello”)。
    109 }

    表达式中的次数、对象、函数和参数部分说明

    1 * subscriber.receive("hello")      // exactly one call
    0 * subscriber.receive("hello")      // zero calls
    (1..3) * subscriber.receive("hello") // between one and three calls (inclusive)
    (1.._) * subscriber.receive("hello") // at least one call
    (_..3) * subscriber.receive("hello") // at most three calls
    _ * subscriber.receive("hello")      // any number of calls, including zero
    1 * subscriber.receive("hello")     // an argument that is equal to the String "hello"
    1 * subscriber.receive(!"hello")    // an argument that is unequal to the String "hello"
    1 * subscriber.receive()            // the empty argument list (would never match in our example)
    1 * subscriber.receive(_)           // any single argument (including null)
    1 * subscriber.receive(*_)          // any argument list (including the empty argument list)
    1 * subscriber.receive(!null)       // any non-null argument
    1 * subscriber.receive(_ as String) // any non-null argument that is-a String
    1 * subscriber.receive({ it.size() > 3 }) // an argument that satisfies the given predicate
                                              // (here: message length is greater than 3)
    1 * subscriber._(*_)     // any method on subscriber, with any argument list
    1 * subscriber._         // shortcut for and preferred over the above
    1 * _._                  // any method call on any mock object
    1 * _                    // shortcut for and preferred over the above

    Stubbing

    对mock对象定义函数的返回值可以用如下方法:

    subscriber.receive(_)>>"ok"

    符号代表函数的返回值,执行上面的代码后,再调用subscriber.receice方法将返回ok。如果要每次调用返回不同结果,可以使用:

    subscriber.receive(_) >>> ["ok", "error", "error", "ok"]

    如果要做额外的操作,如抛出异常,可以使用:

    subscriber.receive(_)>>{thrownewInternalError("ouch")}

    而如果要每次调用都有不同的结果,可以把多次的返回连接起来:

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

    mock and stubbing

    如果既要判断某个mock对象的交互,又希望它返回值的话,可以结合mock和stub,可以这样:

    then:
    1*subscriber.receive("message1")>>"ok"
    1*subscriber.receive("message2")>>"fail"

    注意,spock不支持两次分别设定调用和返回值,如果把上例写成这样是错的:

    setup:
    subscriber.receive("message1")>>"ok"
     
    when:
    publisher.send("message1")
     
    then:
    1*subscriber.receive("message1")

    此时spock会对subscriber执行两次设定:

    第一次设定receive(“message1”)只能调用一次,返回值为默认值(null)。
    第二次设定receive(“message1”)会返回ok,不限制次数。
  • 相关阅读:
    [jenkins] 启动错误 Failed to start LSB: Jenkins Automation Server.
    SpringBoot AOP注解式拦截与方法规则拦截
    JS !function 稀奇古怪的写法
    业务场景后端优化
    对称加密和非对称加密
    第三篇 -- 余生,我累了,也懂了
    第二篇 -- 关东野客书籍
    第十一篇 -- 关于防火墙的一些问题
    第三十一篇 -- 学习第六十八天打卡20190911
    第二十九篇 -- UDP和TCP
  • 原文地址:https://www.cnblogs.com/UniqueColor/p/9327693.html
Copyright © 2011-2022 走看看