ruby-on-rails - Rspec : 存根 ActiveStorage 下载方法
问题描述
我在一个系统上工作,该系统使用 ActiveStorage 在 S3 上存储缓存数据,然后再将其用于其他用途。在我的规范中,我想存根这个文件的下载方法,并加载一个特定的文件以进行测试。
allow(user.cached_data).to receive(:download)
.and_return(read_json_file('sample_data.json'))
(read_json_file
是一个规范助手,File.read
然后JSON.parse
是一个数据文件。)
我收到此错误:
#<ActiveStorage::Attached::One:0x00007f9304a934d8 @name="cached_data",
@record=#<User id: 4, name: "Bob", email: "bob@email.com",
created_at: "2019-08-22 09:11:16", updated_at: "2019-08-22 09:11:16">,
@dependent=:purge_later> does not implement: download
我不明白,文档清楚地说这个对象应该实现下载。
编辑
正如Jignesh和Stephen所建议的那样,我尝试了这个:
allow(user.cached_data.blob).to receive(:download)
.and_return(read_json_file('sample_data.json'))
我收到以下错误:
Module::DelegationError:
blob delegated to attachment, but attachment is nil
user
由 FactoryBot 生成,所以我目前正在尝试将我的cached_data
示例文件附加到该对象。
我的工厂是这样的:
FactoryBot.define do
factory :user
name { 'Robert' }
email { 'robert@email.com' }
after(:build) do |user|
user.cached_data.attach(io: File.open("spec/support/sample_data.json"), filename: 'sample.json', content_type: 'application/json')
end
end
end
但是当我将该after build
块添加到工厂时,我收到以下错误:
ActiveRecord::LockWaitTimeout:
Mysql2::Error::TimeoutError: Lock wait timeout exceeded
也许这是另一个 Stackoverflow 问题。
解决方案
正如其他人在评论中指出的那样,#download
是在ActiveStorage::Blob
类上实现的,而不是ActiveStorage::Attached::One
. 您可以使用以下内容下载该文件:
if user.cached_data.attached?
user.cached_data.blob.download
end
我添加了检查以确保cached_data
已附加,因为blob
代表附件并且如果未附加将失败。
推荐阅读
- javascript - 在 angular 的自定义指令中访问 CSS 变量的最佳方法
- amazon-web-services - Ubuntu Aws 用户会话停止
- ios - SecureField 焦点
- java - 嵌套的maven多模块spring boot项目
- ios - iOS 13.4 是否破坏了 GoogleWebRTC 的视频聊天功能?
- c# - 更改布尔变量值
- github - 如何从 API 捕获项目的最新 GitHub 版本?
- reactjs - 我如何在反应 js 中保持滚动位置和状态的同时回到历史记录
- python - python遍历树的解决方案
- javascript - 如何复制 Node.js 应用程序的当前运行时状态