1

私は自分のコードのテストをもっと始めようとしていましたが、レールの足場のために自動生成されたいくつかのテストのスタイルを模倣しようと思っていました (私は rspec とレールを使用していますが、私の質問は本当に一般的なものです- tdd)。ただし、これらの方法は非常に基本的なものであり、何かを行うという方針に沿っていました。foo の場合は、別のことを行います。if の条件にもう 1 つ 2 つ追加して複雑になるとすぐに、物事が渦巻き始め、ネストされた例がいたるところに表示されるように感じます。これは、やり過ぎのように感じる私が行ってきたことの例です。

まずは方法

def maybe_blah(foo)
  if foo != nil && foos.find_by_id(foo.id) != nil
    blah unless bar?(foo)
  end
end

この方法は非常に簡単です。これが私がそれをテストすることを計画していた方法です

describe maybe_blah

  shared_examples "what happens when bad input is passed" do
    it "doesn't call bar?"...
    it "doesn't call blah"...
  end

  context "when foo is not nil"
    context "when foo is in foos"
      context "bar? returns true"
        it "doesn't call blah" do
           some code involving mocking bar? and blah 
        end
      end

      context "bar? returns false"
        it "does call blah" do
           some code involving mocking bar? and blah 
        end
      end
    end

    context "when foo is not in foos"
       include_examples "what happens when bad input is passed"
    end
  end

  context "when foo is nil"
     include_examples "what happens when bad input is passed"
  end
end

これは、すべてのセットアップとその他のものがそこにある場合のテストよりも著しく短いため (実際に Maybe_blah をテストするには 55 行かかりました)、手に負えなくなっているように見えることがわかります。そのようなやり過ぎのように感じるメソッドをテストする良い方法はありますか?

テストしている条件が 3 つある場合に 3 つの深さのネストを回避する方法はわかりませんが (少なくともこれ以上繰り返すことはありません)、処理していることを確認するためにそれを行う必要があるようです。すべての異なるケース。また、さまざまな悪い入力ごとに失敗の結果をテストするのはばかげているように思えますが、それらの悪い入力で実際に失敗していることを他にどのように知ることができますか?

これは単なるやり過ぎですか?

4

1 に答える 1

1

実際、あなたの条件は次と同じです:

def maybe_blah(foo)
  if foo != nil && foos.find_by_id(foo.id) != nil && !bar?(foo)
    blah
  end
end

したがって、 Decompose ConditionalおよびConsolidate Conditional Expressionテクニックを使用して、別のメソッドに抽出できます。

def maybe_blah(foo)
  blah if can_do_it?(foo)
end

def can_do_it?(foo)
  foo != nil && foos.find_by_id(foo.id) != nil && !bar?(foo)
end

その後、このメソッドを2回テストできますcontexts

describe '#maybe_blah' do
  context 'when can do' do
    # stub can_do_it? and returns true
    # stould receive :blah
  end

  context 'when cant do' do
    # stub can_do_it? and returns false
    # should not receive :blah
  end
end

そして、条件を個別にテストします。

そして、あなたは省略することができます!= nil

def can_do_it?(foo)
  foo && foos.find_by_id(foo.id) && !bar?(foo)
end
于 2013-05-01T06:02:47.407 に答える