Rspec : stubbing ActiveStorage download method

青春壹個敷衍的年華 提交于 2019-12-11 02:31:39

问题


I work on a system that stores cached data on S3 with ActiveStorage before using it for something else. In my spec, I want to stub the download method of this file, and load a specific file for testing purpose.

allow(user.cached_data).to receive(:download)
                       .and_return(read_json_file('sample_data.json'))

(read_json_file is a spec helper that File.read then JSON.parse a data file.)

I get this error :

#<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

I don't get it, the docs clearly say that this object is supposed to implement download.

Edit

As suggested by Jignesh and Stephen, I tried this :

allow(user.cached_data.blob).to receive(:download)
                            .and_return(read_json_file('sample_data.json'))

and I got the following error :

Module::DelegationError:
       blob delegated to attachment, but attachment is nil

user is generated by FactoryBot, so I'm currently trying to attach my cached_data sample file to that object.

My factory looks like that :

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

But when I add that after build block to the factory, I get the following error :

ActiveRecord::LockWaitTimeout:
       Mysql2::Error::TimeoutError: Lock wait timeout exceeded

Maybe it's another Stackoverflow question.


回答1:


As other have pointed out in the comments, #download is implemented on the ActiveStorage::Blob class, not ActiveStorage::Attached::One. You can download the file with the following:

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

I added the check to ensure cached_data is attached because blob delegates to the attachment and would fail if not attached.

Here is the documentation for #download.



来源:https://stackoverflow.com/questions/57609885/rspec-stubbing-activestorage-download-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!