web-dev-qa-db-ja.com

スポック:setup()で定義された相互作用をテストケースで置き換えることはできますか?

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:_ブロックを追加する必要がありますか?

26
John Q Citizen

それはトリッキーなものです。 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"
}

テストメソッドで宣言されたインタラクションが、セットアップメソッドで宣言されたインタラクションを常にオーバーライドするのがよいことに同意します。とにかく、相互作用をオーバーライドするための良い代替手段は、各テストメソッドがそのテストメソッドに期待される相互作用を設定するヘルパーメソッドを呼び出すことです。

24