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?
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.
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).
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.
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.
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With