You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails 4.2使用Puffing Billy Stub第三方图片延迟响应失败

解决RSpec+Capybara+Puffing Billy测试Cloudinary图片加载Spinner的问题

看起来你遇到的核心问题是Puffing Billy的白名单和Stub配置没生效,导致Cloudinary的图片请求要么被完全阻塞,要么Stub没触发,没法模拟慢加载场景。我来一步步帮你排查和修复:

1. 修正白名单配置(关键!)

你日志里的错误Connection to https://res.cloudinary.com:443/... not cached and new http connections are disabled,说明白名单没正确匹配请求。Puffing Billy的whitelist配置需要的是主机名,不是带协议的完整URL。把你的Billy配置里的白名单改成:

c.whitelist = ['localhost', '127.0.0.1', 'res.cloudinary.com']

去掉https://,这样Puffing Billy才会识别这个主机的请求是允许的,不会直接拦截。

2. 修复Stub的写法

你当前的Stub Proc写法有两个问题:

  • 返回的键是code,但Puffing Billy需要的是status
  • 没有返回实际的图片内容,浏览器无法识别图片加载完成,导致Spinner不会消失

修改Stub为:

proxy.stub("https://res.cloudinary.com/demo/image/upload/sample.jpg").and_return(
  Proc.new do |params, headers, body|
    sleep 3  # 用3秒足够测试,不用10秒节省时间
    # 用本地图片Fixture返回,避免依赖外部资源
    image_path = Rails.root.join('spec', 'fixtures', 'sample_image.jpg')
    { 
      status: 200, 
      body: File.read(image_path), 
      headers: { 'Content-Type' => 'image/jpeg' } 
    }
  end
)

记得先在spec/fixtures/目录下放一张测试用的sample_image.jpg。

3. 优化测试逻辑,避免硬编码Sleep

硬编码sleep 15很不可靠,应该用Capybara的内置等待机制:

context "non signed in visitor", js: true, billy: true do
  describe "Spinner shows while waiting then disappears" do
    it "should show spinner during image load and hide afterwards" do
      proxy.stub("https://res.cloudinary.com/demo/image/upload/sample.jpg").and_return(
        Proc.new do |params, headers, body|
          sleep 3
          image_path = Rails.root.join('spec', 'fixtures', 'sample_image.jpg')
          { status: 200, body: File.read(image_path), headers: { 'Content-Type' => 'image/jpeg' } }
        end
      )

      visit actual_deal_page_path(deal)

      # 验证Spinner立即显示
      expect(page).to have_css('div#fullPageLoadingSpinner', visible: :visible, wait: 1)
      # 此时图片不可见
      expect(page).not_to have_css("img[src*='sample.jpg']", visible: :visible, wait: 1)

      # 等待图片加载完成,Spinner隐藏
      expect(page).to have_css('div#fullPageLoadingSpinner', visible: :hidden, wait: 5)
      # 验证图片成功显示
      expect(page).to have_css("img[src*='sample.jpg']", visible: :visible, wait: 5)
    end
  end
end

wait: 5告诉Capybara最多等5秒,直到条件满足,比硬Sleep更稳定。

4. 暂时禁用缓存,确保Stub生效

你的配置里开启了c.cache = true和c.persist_cache = true,如果之前有缓存的Cloudinary请求,Stub可能不会触发。可以暂时把c.cache = false,或者删除缓存目录spec/support/http_cache/billy/,测试通过后再恢复缓存。

5. 确认前端图片加载逻辑正确

最后要确保你的前端JS是正确监听图片加载事件的,比如:

const spinner = document.getElementById('fullPageLoadingSpinner');
const coverImage = document.querySelector('.deal-page-bckdImgCover');

// 图片加载完成后隐藏Spinner
coverImage.addEventListener('load', () => {
  spinner.style.visibility = 'hidden'; // 或者用你项目里的隐藏逻辑
});

// 处理图片加载失败的情况
coverImage.addEventListener('error', () => {
  spinner.style.visibility = 'hidden';
  // 可选:显示错误提示
});

如果前端逻辑没正确绑定事件,即使图片加载了,Spinner也不会消失,这点很容易被忽略。


内容的提问来源于stack exchange,提问作者Mathieu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:25:18