在 rails 控制器测试中遵循 Turblinks.visit()

Follow Turblinks.visit() in rails controller test

我有一个 create.js.erb 模板,其中包含以下内容:

<% if @conversation.errors.any? %>
  $("#form").html("<%= j render(partial: 'form') %>");
<% else %>
  Turbolinks.visit("<%= conversation_url @conversation %>");
<% end %>

我可以像这样使用 assert_select_jquery 轻松测试悲伤的路径:

test 'sad path' do
  # code that causes failure ommitted

  # test that the error explanation div appears
  assert_select_jquery :html, '#form' do
    assert_select 'li', "Body can't be blank"
  end  
end

我在测试快乐路径时遇到问题:

test "happy path" do
  post conversations_url, params: { conversation: attrs }, xhr: true

  # Test that Turbolinks takes us to 
  # the mailbox after successful post 
  assert_select '.flash', "Message sent successfully."
end

测试失败,因为包含成功消息的 flash div 仅在 Turbolinks 调用之后出现。到目前为止我能做的最好的就是测试响应主体是否包含对 Turblinks.visit():

的调用
expected_response = "Turbolinks.visit(\"#{conversation_url conversation}\");"
assert_match /#{expected_response}/, response.body.chomp

但这太恶心了。是否有 rails 方法告诉控制器测试执行 js.erb 文件中可能在请求期间呈现的任何 Turblinks 指令?

execute_javascript_on_page
assert_select :h1, 'xyz'

您需要一个浏览器来执行 JavaScript,因此您需要使用 Rails 指南中的 capybara. I'm not sure which Rails version you use but in Rails 5 browser tests are provided by default. See System Testing 之类的内容进行浏览器测试。之前的版本需要自己安装capybara

话虽这么说,但我确实认为测试对Turbolinks.visit的调用是不好的。我唯一担心的是它可能有点不可读,所以我定义了一个自定义断言,如:

def assert_turbolinks_visit(target_url)
  assert_match(%r{Turbolinks.visit("#{target_url}")}, response.body)
end

然后像这样使用它:

assert_turbolinks_visit(conversation_url(conversation))

如果 Turbolinks.visit 的参数不是文字,可能会出现更多问题。在这种情况下,可能需要进行浏览器测试。