如何访问 Capybara 使用的相同数据库数据

How to access the same DB data that Capybara uses

我有一个非常简单的密码重置表单,它只是一个用于输入电子邮件的文本字段和一个提交按钮。

有一些使用JS的客户端验证,所以我在为它编写规范测试时使用Capyabara JS驱动程序。

此测试仅测试密码重置令牌是否已添加到用户的 auth_info table。

describe "password reset form", js: true do
  let(:email) { "foo@example.com" }

  # Create existing user with an email so we can reset it's password
  let!(:user) { create(:user, email: email) }

  before(:each) do
    fill_in email_field, with: email
    click_button reset_button
  end

  it "generates a new token" do
    # `token` is definitely getting set properly when I pause it here
    # with binding.pry and inspect the object using `user.reload`
    # But when running the test it always shows up as `nil`
    expect(user.reload.auth_info.token).to match(/[A-Fa-f0-9]{32}/)
  end
end

如评论所述,当我使用 binding.pry 直接检查令牌时,我知道令牌已正确设置。但是 RSpec 和 Capybara 将其视为 nil,即使在使用 reload 刷新模型之后也是如此。

Capybara 是否在维护不同的缓存或其他内容?

谢谢!

编辑: 还尝试了将 reload 应用于 User 模型以及 AuthInfo 模型的不同组合,以防万一我也需要刷新后者

您使用的是支持 JS 的浏览器,这意味着 click_button 是异步的。这样做的结果是您正在执行 click_button,然后在按钮触发的操作发生之前立即检查令牌。您可以通过将 sleep 5 放在 expect 之前来验证这一点,测试应该会通过。让测试在检查之前等待的正确方法是使用水豚匹配器在 click_button 完成后在页面上查找更改的信息,类似于以下任一内容

expect(page).to have_text('text that appears after click_button has succeeded')
expect(page).to have_selector('div.abcde') #element that appears after click_button has succeeded

这些会让测试等到操作完成,然后您可以检查令牌