How to check the behavior inside an ActiveRecord creation block?

How can I check such code with rspec?

Foo.create! do |foo| foo.description = "thing" end 

I do not want to check the object that was created - I want to check whether the correct methods were output with the correct objects. Equivalent to testing:

 Foo.create!(description: "thing") 

with this:

 Foo.should_receive(:create!).with(description: "thing") 
+4
source share
3 answers

That's what you need?

 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 
+1
source
 Foo.count.should == 1 Foo.first.description.should == 'thing' 
0
source

Here's a combined approach that combines the best of @antiqe and @Fitzsimmons answers. However, this is much more detailed.

The idea is to make fun of Foo.create in a way that behaves 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 specifications:

 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 can also use FactoryGirl.build_stubbed instead of stub_model . However, you cannot use mock_model , mock or double , since you will have the same problem again.

Now your spec will pass 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 welcome!

0
source

Source: https://habr.com/ru/post/1443371/


All Articles