Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to testing nested attributes in rails?

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?

like image 723
abonec Avatar asked Mar 12 '11 17:03

abonec


People also ask

What is nested attributes Rails?

Nested Attributes is a feature that allows you to save attributes of a record through its associated parent. In this example we'll consider the following scenario: We're making an online store with lots of products. Each Product can have zero or more Variants.

What are nested attributes?

Nested attributes are a way of applying sub-categories to your attributes. For instance, instead of having a single searchable attribute price , you may set up some sub-categories: price.net , price. gross , price. margin (note the use of 'dot notation' here to separate the parent attribute from its child).

How to test controllers in Rails?

The currently accepted way to test rails controllers is by sending http requests to your application and writing assertions about the response. Rails has ActionDispatch::IntegrationTest which provides integration tests for Minitest which is the Ruby standard library testing framework.

How to run test cases in Rails?

We can run all of our tests at once by using the bin/rails test command. Or we can run a single test file by passing the bin/rails test command the filename containing the test cases. This will run all test methods from the test case.


2 Answers

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
like image 88
stuartc Avatar answered Sep 20 '22 18:09

stuartc


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
like image 34
Francis Potter Avatar answered Sep 19 '22 18:09

Francis Potter