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

How to purposely delay an AJAX response while testing with Capybara?

我有一个 React 组件,它模仿了大多数现代社交媒体网站所具有的 "link preview" 功能。你输入一个 link 它会获取图像、标题等...

我通过让 React 组件对我的服务器进行 AJAX 回调以获取 URL 预览数据来做到这一点。

在抓取过程中,我显示一个中间 "loading" 状态(即一些加载图标或纺车)

相关的 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 状态变量在服务器进行抓取时仅在短暂的一秒钟内有效。成功和错误场景都会立即禁用它。

我想在 "loading" 状态下使用我的 Capybara 功能规格测试一些功能。我已经模拟了所有网络调用和服务器返回的数据,但是这一切发生得太快以至于我什至 运行 任何 expect().. 之前它就已经通过了 "loading" 状态声明。我也故意不调用 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

对我如何做到这一点有什么想法吗?

谢谢!

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"}
})