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 // 調(diào)用外部類測試
13 def sum = new Sum();
14 def "get sum"(){
15 expect:
16 sum.sum(1,1) == 2
17 }
18
19 // Where Blocks 簡單大小比較函數(shù)測試
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 // 上述例子實際會跑三次測試,相當(dāng)于在for循環(huán)中執(zhí)行三次測試,如果在方法前聲明@Unroll,則會當(dāng)成三個方法運行。
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另外兩種數(shù)據(jù)定義方法
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應(yīng)用
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調(diào)用send時,兩個subscriber都應(yīng)該被調(diào)用一次receive(“hello”)。
109 }
表達(dá)式中的次數(shù)、對象、函數(shù)和參數(shù)部分說明
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對象定義函數(shù)的返回值可以用如下方法:
subscriber.receive(_)>>"ok"
符號代表函數(shù)的返回值,執(zhí)行上面的代碼后,再調(diào)用subscriber.receice方法將返回ok。如果要每次調(diào)用返回不同結(jié)果,可以使用:
subscriber.receive(_) >>> ["ok", "error", "error", "ok"]
如果要做額外的操作,如拋出異常,可以使用:
subscriber.receive(_)>>{thrownewInternalError("ouch")}
而如果要每次調(diào)用都有不同的結(jié)果,可以把多次的返回連接起來:
subscriber.receive(_) >>> ["ok", "fail", "ok"] >> { throw new InternalError() } >> "ok"
mock and stubbing
如果既要判斷某個mock對象的交互,又希望它返回值的話,可以結(jié)合mock和stub,可以這樣:
then:
1*subscriber.receive("message1")>>"ok"
1*subscriber.receive("message2")>>"fail"
注意,spock不支持兩次分別設(shè)定調(diào)用和返回值,如果把上例寫成這樣是錯的:
setup:
subscriber.receive("message1")>>"ok"
when:
publisher.send("message1")
then:
1*subscriber.receive("message1")
此時spock會對subscriber執(zhí)行兩次設(shè)定:
第一次設(shè)定receive(“message1”)只能調(diào)用一次,返回值為默認(rèn)值(null)。 第二次設(shè)定receive(“message1”)會返回ok,不限制次數(shù)。
總結(jié)
- 上一篇: 差异化学习
- 下一篇: 网页禁止复制的chrome插件办法