1

次のクラスをテストしていると仮定します。

class Processor
  def initialize(tree)
    @tree = tree
  end

  def process(entity)
    @tree.each_branch do |branch|
      branch.inject({}) do |result, fruit|
        result[fruit.name] = fruit.type == entity.type
      end
    end
  end
end

スタブツリーを注入したいのですが、私の仕様では次のようになります。

describe Processor do
  let(:tree) { double("tree") }
  let(:apple) { Fruit.new("apple") }
  let(:processor) { Processor.new(tree) }

  let(:fruit1) { Fruit.new("orange") }
  let(:fruit2) { Fruit.new("apple") }

  it "should process a fruit"
    tree.stub(:each_branch).and_yield([fruit1, fruit2])
    Processor.process(apple)
  end
end

次のハッシュがブロック内に作成されることを期待します。正しく作成され、ブロックの呼び出し元に返されることを確認するにはどうすればよいですか?

{ "orange" => false, "apple" => true }

編集:私はFruitクラスの詳細を省略しました、それは無関係であるはずです。

4

1 に答える 1

1

テストを行うメソッドの途中で結果を取得する必要がある場合は、通常、リファクタリングする必要があることを示す良い兆候です。

次に例を示します。ブランチにメソッドを追加してから、ブランチクラスをテストします(自分が制御しているクラスであると想定します)。

class Branch
  def unique_fruits
    inject({}) do |result, fruit|
      result[fruit.name] = fruit.type == entity.type
    end
  end
end

class Processor
  # snip ...
  def process(entity)
    @tree.each_branch do |branch|
      branch.unique_fruits
    end
  end
end

injectはハッシュを返すため、テストが簡単です。ブランチクラスの単体テストを記述して、そのメソッドを分離できます。次に、このProcessor#processメソッドで、注入ブロックをへの呼び出しに置き換えますbranch.unique_fruits

ブランチを制御できない場合は、ブロックをProcessorクラスの別のメソッドに抽出するだけです。

class Processor
  # snip...

  def process(entity)
    @tree.each_branch do |branch|
      unique_fruits_on_branch(branch)
    end
  end

  def unique_fruits_on_branch(branch)
    branch.inject({}) do |result, fruit|
      result[fruit.name] = fruit.type == entity.type
    end
  end
end

ただし、見た目はそれほど良くないことがわかると思いますProcessor。クラスはさまざまなレベルの抽象化で機能しています。しかし、これらは両方とも単体テストが簡単です。

于 2013-03-26T14:47:58.267 に答える