Rspec 水豚测试 ajax 呼叫未更新记录

Rspec Capybara test with ajax call not updating record

我有一个表单,当用户提交一个带有单个名称字段的 ajax 表单时,会创建一个属于模板对象的记录。这一切手动工作正常,但由于某种原因,当我通过 rspec 测试它时,它告诉我没有创建关联。为什么不在这里更新模板对象?

describe "edit page" do
  before(:each) do
    visit edit_admin_template_path(template)
  end

  context "form sections", js: true do  
    it "allows admin to create one" do
      find("#btn-add-section").click
      within('#new_form_section') do
        fill_in 'Name', with: "Personal Info"
        click_button "Create Section"
      end
      expect(template.form_sections.length).to eq(1)
    end
  end
end

这是我遇到的失败

Failure/Error: expect(template.form_sections.length).to eq(1)

   expected: 1
        got: 0

   (compared using ==)

更新: 刚刚在 rspec 输出中注意到了这一点

An error occurred in an after hook
    ActionView::Template::Error: undefined method `form_sections' for nil:NilClass

所以它告诉我模板对象不存在,然后它可以比较它吗?

UPDATE 2: 所以看起来问题是在等待 ajax 调用在水豚中完成,然后才开始期待。我将它添加到规范中,它现在可以工作了,显然我需要将它重新设置为更好的东西,比如 helper

it "allows admin to create one" do
  find("#btn-add-section").click
  within('#new_form_section') do
    fill_in 'Name', with: "Personal Info"
    click_button "Create Section"
  end
  sleep(10) #this waits for the request to complete
  expect(template.form_sections.length).to eq(1)
end

关键是告诉 RSpec 在执行任何期望之前等待 ajax 调用完成。这是一个很好的 post 我使用的解决方案:

Thoughtbot: Automatically Wait for AJAX with Capybara

为了防止其他人偶然发现这一点,您可以根据 UI 本身进行测试,而不是使用睡眠。如果您使用 have_css 或查找匹配器,水豚将等待该元素重新加载,如下所示:

expect(page).to have_css("#form-page-two", visible: :visible) #这将强制测试等待 ajax 调用

Capybara.automatic_reload 不得设置为 false。 (默认为真)

此策略将减少您的测试套件的 运行 时间;如果测试只用了 2 或 3 秒来加载它只会等待那么久(而不是 10)。

然而,由于间歇性的失败,写起来可能会令人沮丧。为避免这种情况,您可能需要增加等待时间设置。

Capybara.default_max_wait_time = 10

https://github.com/teamcapybara/capybara#asynchronous-javascript-ajax-and-friends