Функциональные тесты Rails- вложенность утверждения в assert_raises?

#ruby-on-rails #ruby-on-rails-3 #tdd

#ruby-on-rails #ruby-on-rails-3 #tdd

Вопрос:

У меня есть функциональный тест, подобный следующему:

 test "vendors can't create notes for products they don't own" do
  login vendor
  params = { format: 'json', note: { content: "shouldn't exist" }, vendor_id: other_product.vendor.id }

  assert_raises(CanCan::AccessDenied) do
    assert_no_difference "Note.count" do
      post :create, params
    end
  end
end
  

При запуске этот тест проходит, но на выходе отображается только 1 утверждение:

 1 tests, 1 assertions, 0 failures, 1 errors, 0 skips
  

Выполняется ли вообще это вложенное assert_no_difference утверждение, поскольку было вызвано AccessDenied исключение?

Если я запущу их как два отдельных утверждения, например:

 assert_raises(CanCan::AccessDenied) do
  post :create, params
end

assert_no_difference "Note.count" do
  post :create, params
end
  

… тест выдает ошибку CanCan::AccessDenied: You are not authorized to access this page. Итак, действительно ли выполняется вложенное утверждение в первом примере? Я знаю, что это несколько избыточно, но это всего лишь пара дополнительных строк кода и обеспечивает некоторое дополнительное спокойствие (но только если это действительно что-то делает).

Ответ №1:

Нет, ваше assert_no_difference утверждение не выполняется, как вы заметили. Создание исключения полностью прерывает блок.

Решение состоит в том, чтобы изменить порядок вложенности ваших утверждений, вот так:

 assert_no_difference "Note.count" do
  assert_raises(CanCan::AccessDenied) do
    post :create, params
  end
end
  

assert_raises Вызов перехватывает исключение, позволяя продолжить выполнение, поэтому внешний блок завершается и Note.count проверка выполняется.