【问题标题】:Rspec : stubbing ActiveStorage download methodRspec : 存根 ActiveStorage 下载方法
【发布时间】:2019-12-27 19:27:01
【问题描述】:

我在一个系统上工作,该系统使用 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

没看懂,the docs 明明说这个对象是要实现下载的。

编辑

按照JigneshStephen 的建议,我尝试了这个:

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 问题。

【问题讨论】:

  • Rails documentation 没有显示任何可用于ActiveStorage::Attached::One 实例的download 方法。
  • 这个方法在 blob 类上:api.rubyonrails.org/classes/ActiveStorage/Blob.html 我以为我的 user.cached_data 会返回一个 blob...
  • 是的downloadActiveStorage::Blob 上可用,但在您的错误中,正在工作的实例是ActiveStorage::Attached::One 类型,即user.cached_data 正在返回ActiveStorage::Attached::One 实例。
  • 请参阅指南中的this,其中提到“您可能还想在模型测试中附加夹具文件。”并检查示例@message.image.attach(io: File.open('/path/to/file'), filename: 'file.pdf'),我想您可以通过在测试中附加文件而不是存根来使用它。
  • 仅供参考,请参阅源 here,了解如何获得 ActiveStorage::Attached::One 实例和 here,了解 blob 如何提供给 ActiveStorage::Attached::One 实例。了解如何使行为可用有助于以正确的方式实现存根。

标签: ruby-on-rails rspec stub rails-activestorage


【解决方案1】:

正如其他人在 cmets 中指出的那样,#download 是在 ActiveStorage::Blob 类上实现的,而不是 ActiveStorage::Attached::One。您可以使用以下内容下载该文件:

if user.cached_data.attached?
  user.cached_data.blob.download
end

我添加了检查以确保已附加 cached_data,因为 blob 代表附件,如果未附加,则会失败。

这里是documentation for #download

【讨论】:

    猜你喜欢
    • 2014-09-23
    • 2013-08-22
    • 1970-01-01
    • 2012-10-24
    • 2015-08-31
    • 1970-01-01
    • 2016-11-04
    • 2016-03-03
    • 1970-01-01
    相关资源
    最近更新 更多