GroovyユニットテストでのSpockの相互作用について何かを理解するのに苦労しています。
私は次のタイプを持っています:
_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/Spockテストを作成しました。
_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
と等しいことを確認します。
2番目のテストでは、bar
モックを変更してgetMessage
メソッドがgoodbye
を返すようにします。次に、foo.getMessage()
(bar.getMessage()
に委任する)がgoodbye
を返すことを期待します。ただし、テストは次のように失敗します。
FooSpec:say goodbye: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:
_ブロックを追加する必要がありますか?
それはトリッキーなものです。 docs で述べられているように、then-blockで宣言されたインタラクションは、以前に宣言されたインタラクションよりも優先されます。ただし、then-blockで宣言されたインタラクションは、前のwhen-blockにスコープされます。 (これにより、複数のwhen-thenペアを持つことができます。)したがって、最後の試行は機能しませんが、次のようになります。
def setup() {
bar.message >> "hello"
}
def "say goodbye"() {
when:
def msg = foo.message
then:
bar.message >> "goodbye"
msg == "goodbye"
}
テストメソッドで宣言されたインタラクションが、セットアップメソッドで宣言されたインタラクションを常にオーバーライドするのがよいことに同意します。とにかく、相互作用をオーバーライドするための良い代替手段は、各テストメソッドがそのテストメソッドに期待される相互作用を設定するヘルパーメソッドを呼び出すことです。