如何在使用Capybara进行测试时故意延迟AJAX响应?

时间:2017-02-28 02:34:26

标签: ruby-on-rails ajax rspec capybara capybara-webkit

我有一个模仿大多数现代社交媒体网站所具有的“链接预览”功能的React组件。您键入一个链接,它会获取图像,标题等...

enter image description here

我这样做是让React组件向我的服务器发出一个AJAX回调来获取URL预览数据。

当它正在取出时我显示​​一个中间的“加载”状态(即一些加载图标或旋转轮)

相关的React代码段似乎是

this.setState({ isLoadingAttachment: true })

return $.ajax({
  type: "GET",
  url: some_url,
  dataType: "json",
  contentType: "application/json",
}).success(function(response){
  // Succesful! Do Success stuff
  component.setState({ isLoadingAttachment: false })
}).error(function(response) {
  // Uh oh! Handle failure stuff
  component.setState({ isLoadingAttachment: false })
});

请注意isLoadingAttachment状态变量仅在服务器执行提取时短暂有效。成功和错误方案都会立即禁用它。

我想在我的“加载”状态下使用我的Capybara功能规格测试一些功能。我已经模拟了所有Web调用以及服务器返回的数据,但这一切都发生得如此之快以至于它在我甚至可以在其上运行任何expect()..语句之前都会通过“加载”状态。我也故意不打电话给wait_for_ajax所以页面会在没有等待ajax的情况下继续,但它仍然太快。

最后我还尝试将服务器调用延迟了1.0秒,但这也没有用。我假设因为整个事情都是单线程的?

# `foo` is an arbitrary method called during the server-side execution
allow_any_instance_of(MyController).
  to receive(:foo) { sleep(1.0) }.and_call_original

关于我如何做到这一点的任何想法?

谢谢!

1 个答案:

答案 0 :(得分:2)

Capybara在与测试不同的线程中启动应用服务器,但是如果您使用默认的Capybara.server设置,您的应用可能会遇到问题,因为它默认使用webrick 。相反,您应该指定Capybara.server = :puma。除此之外,模拟响应通常是功能规范中的一个坏主意(通常意味着端到端测试),因为这意味着您不再按照它在生产中运行的方式实际测试您的应用程序代码。更好的解决方案是使用类似puffing-billy - https://github.com/oesmith/puffing-billy的内容来模拟应用代码之外的网络响应,这样您就可以执行类似

的操作
proxy.stub('https://example.com/proc/').and_return(Proc.new { |params, headers, body|
  sleep 2
  { :text => "Your results"}
})