2014-03-06 57 views
20

我在Groovy單元測試中很難理解有關Spock交互的內容。Spock:可以在測試用例中替換setup()中定義的交互嗎?

我有以下幾種類型:

public interface Bar { 
    public String getMessage(); 
} 

public class Foo { 
    private Bar bar; 
    public void setBar(Bar bar) { 
    this.bar = bar; 
    } 
    public String getMessage() { 
    return bar.getMessage(); 
    } 
} 

,然後我寫了下面的Groovy /斯波克測試:

class FooSpec extends Specification { 

    private Bar bar; 
    private Foo foo; 

    def setup() { 
    bar = Mock(Bar) { getMessage() >> "hello" } 
    foo = new Foo() 
    foo.bar = bar 
    } 

    def "say hello"() { 
    expect: 
    foo.message.equals("hello") 
    } 

    def "say goodbye"() { 
    setup: 
    bar.getMessage() >> "goodbye" 

    expect: 
    foo.message.equals("goodbye") 
    } 
} 

的代碼創建在設置一個模擬Bar實例初始化Bar.getMessage()返回hello,並將其分配給新的Foo實例。

第一個測試驗證foo.getMessage()等於hello

第二個測試試圖修改bar模擬,以便它的getMessage方法返回goodbye。然後我們預計foo.getMessage()(代表bar.getMessage())將返回goodbye。然而,測試如下失敗:

FooSpec:說再見:26條件不滿足

因爲foo.message仍然等於hello

我也試過如下:

def "say goodbye"() { 
    when: 
    bar.getMessage() >> "goodbye" 

    then: 
    foo.message.equals("goodbye") 
} 

和:

def "say goodbye"() { 
    when: 
    no_op() 

    then: 
    bar.getMessage() >> "goodbye" 
    foo.message.equals("goodbye") 
} 

但都無法與同招呼不等於告別消息。

我可能還在考慮在模式的Mockito,並假定的相互作用是when(...).thenReturn(...)表達的等價物,而後來的相互作用會覆蓋前面的相互作用。

是否有一種使用Spock在setup方法中聲明交互的簡單方法,然後在測試用例中覆蓋該交互?或者我需要刪除setup()方法,並基本上添加一個setup:塊到每個測試用例?

回答

19

這是一個棘手的問題。如docs中所述,在then-block中聲明的交互優先於早先聲明的交互。然而,在then塊中聲明的交互作用範圍是前一個when塊。 (這允許有多個時,則對)。因此您的最後一次嘗試不起作用,但下面的意志:

def setup() { 
    bar.message >> "hello" 
} 

def "say goodbye"() { 
    when: 
    def msg = foo.message 

    then: 
    bar.message >> "goodbye" 
    msg == "goodbye" 
} 

我同意,這將是很好的測試方法始終覆蓋相互作用宣佈相互作用在設置方法中聲明。無論如何,覆蓋交互的一個很好的選擇是每個測試方法調用一個幫助方法,爲該測試方法設置預期的交互。

+0

感謝您的評論。我將避免使用'setup()'方法並改變我的測試方法以直接初始化它們的狀態(這也是因爲我經常在我的測試方法中使用'where:'塊,並發現我驚訝的是'setup()'方法是在'where:'塊之後調用的)。我認爲*我可以理解你的上面的例子,但它不直觀(它仍然看起來像'then:'塊中的設置代碼給我)。 –

+0

@PeterNiederwieser,你在這個例子中使用了什麼Spock版本?我們已經嘗試了這個以及Spock 1.0中的很多其他變體,但它沒有奏效。 – falsarella

相關問題