How to test nested attributes in rails?

I have a rail controller defined here:

https://github.com/abonec/Simple-Store/blob/master/app/controllers/carts_controller.rb

On the cart page, the user can specify the number of lines by sending nested attributes. The parameters are as follows:

{ "cart" => { "line_items_attributes" => { "0" => { "quantity" => "2", "id" => "36" } } }, "commit" => "Update Cart", "authenticity_token" => "UdtQ+lchSKaHHkN2E1bEX00KcdGIekGjzGKgKfH05So=", "utf8"=>"\342\234\223" } 

In my controller action, these parameters are saved as follows:

 @cart.update_attributes(params[:cart]) 

But I do not know how to test this behavior in a test. @cart.attributes only generates model attributes, not nested attributes.

How can I test this behavior? How to simulate a mail request with nested attributes in my functional tests?

+7
source share
4 answers

It's a bit late to the party, but you shouldn't test this behavior from the controller. Nested attributes are model behavior. The controller simply passes something to the model. There is no mention of any nested attributes in your controller example. You want to check for the behavior created by accepts_nested_attributes_for in your model

You can verify this with rSpec as follows:

 it "should accept nested attributes for units" do expect { Cart.update_attributes(:cart => {:line_items_attributes=>{'0'=>{'quantity'=>2, 'other_attr'=>"value"}}) }.to change { LineItems.count }.by(1) end 
+5
source

Assuming you are using Test :: Unit and you have a basket in @cart in the setup, try something like this in your upgrade test:

 cart_attributes = @cart.attributes line_items_attributes = @cart.line_items.map(&:attributes) cart_attributes[:line_items] = line_items_attributes put :update, :id => @cart.to_param, :cart => cart_attributes 
+3
source

Using test/unit in Rails3, first create an integration test:

 rails g integration_test cart_flows_test 

in the generated file in which you include the test, for example:

 test "if it adds line_item through the cart" do line_items_before = LineItem.all # don't forget to sign in some user or you can be redirected to login page post_via_redirect '/carts', :cart => {:line_items_attributes=>{'0'=>{'quantity'=>2, 'other_attr'=>"value"}}} assert_template 'show' assert_equal line_items_before+1, LineItem.all end 

I hope this helps.

+1
source

After updating the basket with nested attributes, you can access the nested attributes by doing

 @cart.line_items 
0
source

All Articles