使用Rspec + Timecop + Capybara + Capybara Webkit进行集成测试中出现Capybara :: FrozenInTime错误

11

我在一些集成测试中看到了一个错误,使用rspec、capybara、capybara-webkit和timecop。

Capybara::FrozenInTime:
   time appears to be frozen, Capybara does not work with libraries which freeze time, consider using time travelling instead
我知道的唯一一个冻结时间的gem是Timecop,但我并没有在测试失败的情况下使用它。
由于错误只会有时发生,所以即使改变了什么,我也无法确定它是否已经消失了。

这是一个很棒的错误信息! - zetetic
1
当我对Time#now进行存根和类似操作时,我会遇到这个错误。切换到Timecop,并确保Timecop真正返回,似乎可以解决它。 - Anders Kindberg
2个回答

11

错误消息的结尾给出了解决方案:

考虑使用时间旅行代替

只需将Timecop.freeze更改为Timecop.travelTimecop.freeze破坏Capybara的自动等待功能。

此外,我建议在after代码块中调用Timecop.return,因为它将与最近的时间旅行块相关联:

after :each do
  Timecop.return
end

1
事情是这样的:在这种情况下,我真的需要冻结时间。通常我总是使用travel,但有些测试需要秒级精度。 - hsgubert

6
我找到的解决方案是添加:
before :each do
  Timecop.return
end

spec_helper.rb 文件中,我们可以保证在每个测试之前时间不会被冻结。虽然只有在使用与 rack-test 不同的 webdriver(如我的情况下使用的 capybara-webkit)才存在此问题。

你是否有可能在测试中冻结时间时,没有将Timecop.return添加到after块中? - zetetic
我想我可以把Timecop.return放在一个after块中,但是Timecop.freeze通常接收一个块,即使用冻结时间执行的proc。假设在块关闭后时间会恢复正常。 - hsgubert
3
在您的spec_helper中,应启用安全模式, 方法为 Timecop.safe_mode = true。这将使 Timecope.freeze 需要一个块(block),这意味着时间会解冻。请注意不要改变原始意思。 - Derek Prior

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接