Reputation: 22751
How can I test code like this with rspec?
Foo.create! do |foo|
foo.description = "thing"
end
I don't want to test of the object was created -- I want to test if the right methods were invoked with the right objects. Equivalent to testing this:
Foo.create!(description: "thing")
with this:
Foo.should_receive(:create!).with(description: "thing")
Upvotes: 4
Views: 143
Reputation: 15950
Here's a combination approach that merges the best from @antiqe's and @Fitzsimmons' answers. It is significantly more verbose though.
The idea is to mock Foo.create in a way that behaves more like AR::Base.create. Frist, we define a helper class:
class Creator
def initialize(stub)
@stub = stub
end
def create(attributes={}, &blk)
attributes.each do |attr, value|
@stub.public_send("#{attr}=", value)
end
blk.call @stub if blk
@stub
end
end
And then we can use it in our specs:
it "sets the description" do
f = stub_model(Foo)
stub_const("Foo", Creator.new(f))
Something.method_to_test
f.description.should == "thing"
end
You could also use FactoryGirl.build_stubbed
instead of stub_model
. You can't, however, use mock_model
, mock
or double
since you would have the same problem again.
Now your spec will pass for any of the following code snippets:
Foo.create(description: "thing")
Foo.create do |foo|
foo.descrption = "thing"
end
foo = Foo.create
foo.descrption = "thing"
Feedback is appreciated!
Upvotes: 0
Reputation: 1591
Is this what you're after?
it "sets the description" do
f = double
Foo.should_receive(:create!).and_yield(f)
f.should_receive(:description=).with("thing")
Something.method_to_test
end
Upvotes: 1