8

I have a rails controller, defined here:

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

On the cart page a user can specify the quantity of line_items by posting nested attributes. The parameters look like this:

{ "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 params are saved like this:

@cart.update_attributes(params[:cart])

But I don't 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 post request with nested attributes in my functional tests?

0

4 Answers 4

8

A little late to the party, but you shouldn't be testing that behavior from the controller. Nested attributes is model behavior. The controller just passes anything to the model. In your controller example, there is no mention of any nested attributes. You want to test for the existence of the behavior created by accepts_nested_attributes_for in your model

You can test this with rSpec like this:

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
Sign up to request clarification or add additional context in comments.

1 Comment

Cart.update_attributes won't work because it should be called on an instance of Cart not Cart itself.
3

Assuming you're using Test::Unit, and you have a cart in @cart in the setup, try something like this in your update 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

Comments

2

Using test/unit in Rails3, first generate a integration test:

rails g integration_test cart_flows_test

in the generated file you include you test, something like:

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 that helped.

Comments

0

After you update the cart with the nested attributes, you can access the nested attributes by doing

@cart.line_items

1 Comment

How to access to nested attributes I know, but I don't know how to simulate post request with nested attributes in my functional tests.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.