1

は最近、ブロックが呼び出されたかどうかを RSpec でテストする方法を尋ねました。その質問に対する答えは、単純なケースでうまくいくようです。問題は、ブロックでの初期化がより複雑な場合です。次にbefore、コンテキスト内のさまざまなテストで行われ、再利用されます。その中には、ブロックが評価されたかどうかをテストするものがあります。例を参照してください。

context "the node definition using block of code" do
  before do
     @n=node do
        # this block should be called
     end
     # some more complex setup concerning @n
  end

  it "should call the block" do
     # how to test it?
  end

  # here a bunch of other tests using @n

end

この場合、ローカル変数の値を変更する副作用を伴うソリューションは機能しません。他のテストで使用するには、ステートメント全体を適切に評価する必要があるため、ブロックから例外を発生させても意味がありません。

明らかに、テストを個別に実行できますが、初期化部分をコピーして貼り付ける必要があり、ブロックと呼ばれるテストは本質的にこのコンテキストに属しているため、悪臭を放っているようです。

そのような場合にブロックが評価されたかどうかをテストするにはどうすればよいですか?


以下の@zeteticによる質問の説明。

コンテキストは、パラメーターとコードのブロック (ノードのスコープ内で何か他のものを定義できる) によって定義されたノードを使用して、一種の DSL を実装していることです。ノードのブロックによって定義されるものは非常に一般的なものになる可能性があるため、少なくとも最初の試行では、ブロックが評価され、ユーザーがそこに提供するものが考慮されることを確認する必要があります。今のところ、それが何であるかは問題ではありません。

おそらく、今すぐテストをリファクタリングし、モックを使用して、実装ではなく動作をテストする必要があります。ただし、いくつかの mixin と、オブジェクトに送信されたメッセージの動的処理のために、少し注意が必要です。今のところ、そのようなテストの概念は私の頭の中では少し曖昧です ;-)

とにかく、あなたの回答とコメントは、RSpec がどのように機能するかをよりよく理解するのに役立ち、私がやろうとしていることが RSpec に適合しないかのように見える理由を説明してくれました。

4

1 に答える 1

1

このようなことを試してください(私はテストしていません):

context "the node definition using block of code" do
  let(:node){
    node = Node.new "arg1", "arg2", node_block
    # more complex stuff here
    node
  }
  context "checking the block is called" do
    let(:node_block) {
      double = double("node_block")
      double.should_receive("some kind of arg").and_return("something")
      # this will now cause a fail if it isn't called
      double
    }
    it "should call the block" do
      node.blah()
    end
  end

  let(:node_block) {
    # some real code
  }

  subject { node.blah() }
  it { should == 2 }
  # ...
end

したがって、これは非常に不安定なコードです (先に進むためにあまり与えていないため、ギャップを埋める必要があり、let明らかにラムダでもあります。つまり、それをいじる必要がある可能性がありますビット)letと aを使用しdoubleて呼び出されたことを確認し、 の使用を回避します。これは、仕様で使用する変数を設定しないというbefore副作用のためです。

@zetetic は、ここで動作をテストしていないという非常に洞察に満ちたコメントをしています。私は単体テスト スタイルの処理を行うために rspec を使用することに反対しているわけではありません (ガイドラインは破られるように作られています) が、コードの実際のブロックを使用した場合、そのブロックが呼び出されていない場合に、後のテストがどのようにパスするかを疑問に思うかもしれません。ある意味では、ブロックが呼び出されていることを確認する必要があるかどうかさえわかりませんが、知っているのはあなただけです。

于 2012-11-08T09:13:19.993 に答える