RSpec测试Shop的company_logo上传时ActiveStorage计数不变问题
问题根因
你在测试中指定了as: :json参数,JSON格式不支持二进制文件传输,因此你传入的fixture_file_upload对象没有被正确解析到控制器参数中,导致附件没有保存成功。Postman请求能成功是因为你使用了multipart/form-data格式发送请求,和测试用的请求格式不一致。
修复步骤
- 修改测试请求格式:去掉测试代码中的
as: :json参数,让Rails默认发送multipart/form-data格式的请求即可,也可以显式指定as: :multipart。
如果你在valid_headers中硬写了Content-Type: application/json,请移除这个写死的配置,让Rails自动生成带boundary的multipart请求头。 - 检查基础配置:
- 确认Shop模型已添加
has_one_attached :company_logo配置 - 确认
shop_params参数白名单中已加入company_logo字段,控制器中你标注为调试用的手动attach代码属于冗余逻辑,建议直接删除
- 确认Shop模型已添加
- 校验前重载模型:测试中校验附件状态前需要重载内存中的Shop对象,否则读取到的是更新前的状态。
完整可用测试示例
RSpec.describe "Shops update", type: :request do let(:shop) { Shop.create! valid_attributes } let(:company_logo) { fixture_file_upload('400x400.png', 'image/png') } let(:params) { { shop: { name: "SHopName", company_logo: company_logo } } } subject { patch shop_url(shop), params: params, headers: valid_headers(admin) } it '返回正确状态码' do subject expect(response).to have_http_status :ok end it '成功创建存储Blob' do expect { subject }.to change { ActiveStorage::Blob.count }.from(0).to(1) end it "成功关联店铺logo" do subject expect(shop.reload.company_logo).to be_attached end it "正确增加附件关联记录" do expect { subject }.to change(ActiveStorage::Attachment, :count).by(1) end end
内容的提问来源于stack exchange,提问作者Jan
相关产品推荐
相关产品推荐

