在 RSpec 中存根来自 S3 的 Paperclip 下载
Stubbing Paperclip downloads from S3 in RSpec
我正在使用 Paperclip/RSpec,Whosebug 已帮助我使用以下代码成功地将文件上传存根到 S3:
spec/rails_helper.rb
config.before(:each) do
allow_any_instance_of(Paperclip::Attachment).to receive(:save).and_return(true)
end
效果很好。
在我的模型上,我有两个 Paperclip 字段:
class MyModel < ActiveRecord::Base
has_attached_file :pdf
has_attached_file :resource
end
我的代码使用 #copy_to_local_file method
(Docs) 从 S3 检索文件。
#copy_to_local_file
有两个参数:样式(:original
、:thumbnail
等)和要复制到的本地文件路径。
示例:
MyModel.resource.copy_to_local_file(:original, local_file.path)
当被测系统尝试访问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
我意识到这些错误的发生是因为上传到 S3 的文件被存根了,所以当它遇到 MyModel#pdf#copy_to_local_file
或 MyModel#resource#copy_to_local_file
时,它会尝试抓取 S3 中不存在的文件。
当前解:
我已经设法消除了上述错误,但我觉得这不是一个完整的解决方案,并且给我的测试带来了错误的安全感。我的半解决方案是按以下方式存根此方法:
spec/rails_helper.rb
before(:each) do
allow_any_instance_of(Paperclip::Storage::S3).to receive(:copy_to_local_file)
end
虽然这确实排除了 #copy_to_local_file
方法并删除了错误,但它实际上并没有将任何内容写入作为 #copy_to_local_file
的第二个参数提供的本地文件,因此它不能完全模拟从 S3 下载的文件。
问题:
有没有办法存根 #copy_to_local_file
并将我的 spec/factories/files
目录中固定文件的内容写入本地文件(它的第二个参数)?
还是我想多了?这是我不应该担心的事情吗?
您无需担心 'downloaded' 文件是否实际存在于您的测试中。你已经决定去掉 Paperclip,所以彻底地去掉 #save
和 #copy_to_file
。您可能还需要从文件系统中删除对下载文件的读取。
所有这些存根都会增加集成错误的可能性,因此您可能应该编写一个功能规范(使用像 poltergeist 这样的强制浏览器)来实际上传和下载一些东西并从文件系统读取它。
就是说,您可以通过将一个块传递给 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
我正在使用 Paperclip/RSpec,Whosebug 已帮助我使用以下代码成功地将文件上传存根到 S3:
spec/rails_helper.rb
config.before(:each) do
allow_any_instance_of(Paperclip::Attachment).to receive(:save).and_return(true)
end
效果很好。
在我的模型上,我有两个 Paperclip 字段:
class MyModel < ActiveRecord::Base
has_attached_file :pdf
has_attached_file :resource
end
我的代码使用 #copy_to_local_file method
(Docs) 从 S3 检索文件。
#copy_to_local_file
有两个参数:样式(:original
、:thumbnail
等)和要复制到的本地文件路径。
示例:
MyModel.resource.copy_to_local_file(:original, local_file.path)
当被测系统尝试访问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
我意识到这些错误的发生是因为上传到 S3 的文件被存根了,所以当它遇到 MyModel#pdf#copy_to_local_file
或 MyModel#resource#copy_to_local_file
时,它会尝试抓取 S3 中不存在的文件。
当前解:
我已经设法消除了上述错误,但我觉得这不是一个完整的解决方案,并且给我的测试带来了错误的安全感。我的半解决方案是按以下方式存根此方法:
spec/rails_helper.rb
before(:each) do
allow_any_instance_of(Paperclip::Storage::S3).to receive(:copy_to_local_file)
end
虽然这确实排除了 #copy_to_local_file
方法并删除了错误,但它实际上并没有将任何内容写入作为 #copy_to_local_file
的第二个参数提供的本地文件,因此它不能完全模拟从 S3 下载的文件。
问题:
有没有办法存根 #copy_to_local_file
并将我的 spec/factories/files
目录中固定文件的内容写入本地文件(它的第二个参数)?
还是我想多了?这是我不应该担心的事情吗?
您无需担心 'downloaded' 文件是否实际存在于您的测试中。你已经决定去掉 Paperclip,所以彻底地去掉 #save
和 #copy_to_file
。您可能还需要从文件系统中删除对下载文件的读取。
所有这些存根都会增加集成错误的可能性,因此您可能应该编写一个功能规范(使用像 poltergeist 这样的强制浏览器)来实际上传和下载一些东西并从文件系统读取它。
就是说,您可以通过将一个块传递给 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