在RSpec中从S3下载Stubbing Paperclip

时间:2021-07-16 21:07:54

I am using Paperclip/RSpec and * has helped me successfully stub file uploads to S3 using this code:

我正在使用Paperclip / RSpec,*使用以下代码帮助我成功将文件上传到S3:

spec/rails_helper.rb

config.before(:each) do
  allow_any_instance_of(Paperclip::Attachment).to receive(:save).and_return(true)
end

This is working great.

这很有效。

On my model I have two Paperclip fields:

在我的模型上,我有两个Paperclip字段:

class MyModel < ActiveRecord::Base
  has_attached_file :pdf
  has_attached_file :resource
end

My code uses the #copy_to_local_file method (Docs) to retrieve a file from S3.

我的代码使用#copy_to_local_file方法(Docs)从S3检索文件。

#copy_to_local_file takes two params: the style (:original, :thumbnail, etc) and the local file path to copy to.

#copy_to_local_file有两个参数:样式(:原始,:缩略图等)和要复制到的本地文件路径。

Example:

MyModel.resource.copy_to_local_file(:original, local_file.path)

When the system under test tries to access MyModel#pdf#copy_to_local_file or MyModel#resource#copy_to_local_file, I originally got errors like the following:

当被测系统尝试访问MyModel#pdf#copy_to_local_file或MyModel#resource#copy_to_local_file时,我最初遇到如下错误:

No Such Key - cannot copy /email_receipts/pdfs/000/000/001/original/email_receipt.eml.pdf to local file /var/folders/4p/1mm86g0n58x7d9rvpy88_s9h0000gn/T/receipt20150917-4906-13evk95.pdf
No Such Key - cannot copy /email_receipts/resources/000/000/001/original/email_receipt.eml to local file /var/folders/4p/1mm86g0n58x7d9rvpy88_s9h0000gn/T/resource20150917-4906-1ysbwr3.eml

I realize these errors were happening because uploads to S3 are stubbed, so when it encounters MyModel#pdf#copy_to_local_file or MyModel#resource#copy_to_local_file it tries to grab a file in S3 that isn't there.

我意识到这些错误正在发生,因为上传到S3是存根的,所以当遇到MyModel#pdf#copy_to_local_file或MyModel#resource#copy_to_local_file时,它会尝试在S3中抓取一个不存在的文件。

Current Solution:

I've managed to quash the errors above, but I feel it's not a complete solution and gives my tests a false sense of security. My half-solution is to stub this method in the following way:

我已经设法消除了上面的错误,但我觉得这不是一个完整的解决方案,并且给我的测试带来了错误的安全感。我的半解决方案是以下列方式存根此方法:

spec/rails_helper.rb

before(:each) do
  allow_any_instance_of(Paperclip::Storage::S3).to receive(:copy_to_local_file)
end

While this does stub out the #copy_to_local_file method and removes the errors, it doesn't actually write any content to the local file that is provided as the second argument to #copy_to_local_file, so it doesn't quite simulate the file being downloaded from S3.

虽然这确实会删除#copy_to_local_file方法并删除错误,但它实际上并没有将任何内容写入作为#copy_to_local_file的第二个参数提供的本地文件,因此它不能完全模拟从S3下载的文件。

Question:

Is there a way to stub #copy_to_local_file AND have it write the contents of a canned file in my spec/factories/files directory to the local file (its second argument)?

有没有办法存根#copy_to_local_file并让它将我的spec / factories / files目录中的固定文件的内容写入本地文件(它的第二个参数)?

Or am I overthinking this? Is this something I shouldn't be worrying about?

还是我在思考这个?这是我不应该担心的吗?

1 个解决方案

#1


0  

You don't need to worry about whether the 'downloaded' files actually exist in your tests. You've decided to stub out Paperclip, so do it completely, by stubbing out both #save and #copy_to_file. You may also need to stub out reads of downloaded files from the filesystem.

您无需担心测试中是否存在“已下载”文件。你已经决定使用#save和#copy_to_file来完成Paperclip,所以要完全这样做。您可能还需要从文件系统中读取下载文件的读取。

All this stubbing raises the possibility of integration errors, so you should probably write a feature spec (using a captive browser like poltergeist) that actually uploads and downloads something and reads it from the filesystem.

所有这些存根都会增加集成错误的可能性,因此您应该编写一个功能规范(使用像poltergeist这样的强制浏览器)实际上传和下载内容并从文件系统中读取内容。

That said, you can do anything you want in an RSpec stub by passing it a block:

也就是说,你可以通过传递一个块来在RSpec存根中做任何你想做的事情:

allow_any_instance_of(Paperclip::Storage::S3).to receive(:copy_to_local_file) do |style, local_dest_path|
  # write a file here, or do anything you like
end

#1


0  

You don't need to worry about whether the 'downloaded' files actually exist in your tests. You've decided to stub out Paperclip, so do it completely, by stubbing out both #save and #copy_to_file. You may also need to stub out reads of downloaded files from the filesystem.

您无需担心测试中是否存在“已下载”文件。你已经决定使用#save和#copy_to_file来完成Paperclip,所以要完全这样做。您可能还需要从文件系统中读取下载文件的读取。

All this stubbing raises the possibility of integration errors, so you should probably write a feature spec (using a captive browser like poltergeist) that actually uploads and downloads something and reads it from the filesystem.

所有这些存根都会增加集成错误的可能性,因此您应该编写一个功能规范(使用像poltergeist这样的强制浏览器)实际上传和下载内容并从文件系统中读取内容。

That said, you can do anything you want in an RSpec stub by passing it a block:

也就是说,你可以通过传递一个块来在RSpec存根中做任何你想做的事情:

allow_any_instance_of(Paperclip::Storage::S3).to receive(:copy_to_local_file) do |style, local_dest_path|
  # write a file here, or do anything you like
end