Reputation: 2421
Assume I am testing the following class:
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
I'd like to inject a stubbed tree, in my spec I would have:
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
I would expect the following hash to be created in the block. How do I verify that it is created correctly and returned to the caller of the block?
{ "orange" => false, "apple" => true }
EDIT: I omitted details of the Fruit class, it should be irrelevant.
Upvotes: 1
Views: 41
Reputation: 11951
If you're ever having to try and catch the result somewhere in the middle of a method that your testing, it's normally a good sign that you need to refactor.
Here's an example: add a method to the branch, then test the branch class (assuming it's a class that you're in control of).
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
That's easier to test, as inject returns the hash. You can write a unit test for the branch class and isolate that method. Then in the Processor#process
method you replace the inject block with a call to branch.unique_fruits
.
If you don't have control over branch, just extract the block to another method on the Processor
class:
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
However, you can probably see that it doesn't look as nice - the Processor
class is working at different levels of abstraction. But both of these are easier to unit test.
Upvotes: 1