Как тестировать вложенные атрибуты в рельсах?

У меня есть контроллер рельсов, определенный здесь:

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

На странице корзины пользователь может указать количество line_items, опубликовав вложенные атрибуты. Параметры выглядят так:

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

В моем действии контроллера эти параметры сохраняются следующим образом:

@cart.update_attributes(params[:cart])

Но я не знаю, как проверить это поведение в тесте. @cart.attributes генерирует только атрибуты модели, а не вложенные атрибуты.

Как я могу проверить это поведение? Как имитировать почтовый запрос с вложенными атрибутами в моих функциональных тестах?


person abonec    schedule 12.03.2011    source источник


Ответы (4)


Немного опоздал на вечеринку, но вы не должны тестировать такое поведение с контроллера. Вложенные атрибуты — это поведение модели. Контроллер просто передает что-либо модели. В вашем примере с контроллером нет упоминания о каких-либо вложенных атрибутах. Вы хотите проверить наличие поведения, созданного accepts_nested_attributes_for в вашей модели.

Вы можете проверить это с помощью rSpec следующим образом:

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
person stuartc    schedule 10.04.2012
comment
Cart.update_attributes не будет работать, потому что его следует вызывать для экземпляра Cart, а не для самой Cart. - person Khalil Gharbaoui; 01.04.2021

Предполагая, что вы используете Test::Unit и у вас есть корзина в @cart в настройках, попробуйте что-то вроде этого в своем тесте обновления:

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
person Francis Potter    schedule 12.08.2011

Используя test/unit в Rails3, сначала сгенерируйте интеграционный тест:

rails g integration_test cart_flows_test

в сгенерированном файле, который вы включаете в свой тест, что-то вроде:

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

Я надеюсь, что это помогло.

person Marco Antonio    schedule 22.04.2011

После обновления корзины вложенными атрибутами вы можете получить доступ к вложенным атрибутам, выполнив

@cart.line_items
person Mike Lewis    schedule 12.03.2011
comment
Как получить доступ к вложенным атрибутам я знаю, но я не знаю, как имитировать почтовый запрос с вложенными атрибутами в моих функциональных тестах. - person abonec; 13.03.2011