带有载波的 Rails 3 测试夹具?
Posted
技术标签:
【中文标题】带有载波的 Rails 3 测试夹具?【英文标题】:Rails 3 test fixtures with carrierwave? 【发布时间】:2011-11-23 23:05:47 【问题描述】:我正在努力从 attachment_fu 升级到carrierwave,因为 attachment_fu 在 rails 3 中损坏了。
没有一个测试能够运行,因为我们有无效的固定装置,它们使用来自 attachment_fu 的语法来处理附件文件。
例如,我们有一个包含一个 PostAttachment 的 Post 模型。 PostAttachment 夹具中的数据如下所示:
a_image:
post_id: 1
attachment_file: <%= Rails.root>/test/files/test.png
这是我得到的错误:
ActiveRecord::StatementInvalid: PGError: ERROR: column "attachment_file" of relation "post_attachments" does not exist
LINE 1: INSERT INTO "post_attachments" ("post_id", "attachment_file"...
attachment_file
会被attachment_fu 拾取,它会负责为模型创建attachment_fu 附件的所有处理。
有没有办法在灯具中添加图片附件,但使用 CarrierWave 代替?
【问题讨论】:
【参考方案1】:我设法让它工作的唯一方法是使用专门用于测试的存储提供程序,它实际上并不保存/读取文件。
在您的config/initializers/carrier_wave.rb
中添加一个 NullStorage 类,该类实现存储提供程序的最小接口。
# NullStorage provider for CarrierWave for use in tests. Doesn't actually
# upload or store files but allows test to pass as if files were stored and
# the use of fixtures.
class NullStorage
attr_reader :uploader
def initialize(uploader)
@uploader = uploader
end
def identifier
uploader.filename
end
def store!(_file)
true
end
def retrieve!(_identifier)
true
end
end
然后在初始化 CarrierWave 的时候为测试环境添加一个子句,例如,
if Rails.env.test?
config.storage NullStorage
end
这里有一个gist of my complete carrier_wave.rb 供参考。它还包括如何设置 S3 以在暂存/生产中上传和本地存储以进行开发,以便您了解如何在上下文中配置 CarrierWave。
配置好 CarrierWave 后,您可以简单地将任何字符串放在 fixtures 列中来模拟上传的文件。
【讨论】:
当我在工厂尝试使用文件 arg 时,我收到了ArgumentError: is not a recognized storage provider
错误。正如您所建议的,转换为字符串可以使其工作!耶!谢谢!
嗯,我很有希望,但是......当我访问一个页面时,我的功能规范中包含表单字段,这仍然显示为“不是公认的存储提供商”。有没有办法将 NullStorage 注册为公认的提供者??
我不完全确定 NullStorage 的作用;但是我有单元测试可以做一些事情,比如通过电子邮件发送以前上传的文件的附件——如何测试这些?我尝试了上述步骤,但它们似乎没有帮助。谢谢。
我设置了雾 - 我收到一个错误:bucket_name is required
当您验证上传文件是否存在时,这意味着什么?如果NullStorage
没有实际存储您的文件...【参考方案2】:
尝试传递文件而不是字符串。
a_image:
post_id: 1
attachment_file: File.open(Rails.root.join("test/files/test.png"))
这适用于我使用FactoryGirl
注意:编辑感谢 @dkobozev
【讨论】:
File.open(Rails.root + "/test/files/test.png")
对我不起作用。 File.open(Rails.root.join("test/files/test.png"))
会。
在当前版本的carrierwave上,这对我不起作用。我试过引用/转义/ERBing 上面的File.open...
调用。我也尝试过使用Rack::Test::UploadedFile.new(Rails.root.join("test/files/test.png"))
,它在作为参数传递时有效。
这不适用于灯具。如果不出意外,您将不得不使用 ERB 标签转义 Ruby 代码,但即便如此它也不起作用。
这在 Rails 4.1 中对我也不起作用,我最终做的是在测试中将文件分配给它们各自的属性。不知道这个方法有什么问题,但是通过了...
这对我有用,但为了将它与固定装置一起使用,我需要添加 attachment_file: <%= File.open(Rails.root.join("test/files/test.png")) %>
【参考方案3】:
config/initializers/carrier_wave.rb
在 Rails 4 中
# class NullStorage is defined here before the following block
if Rails.env.test?
CarrierWave.configure do |config|
config.storage NullStorage
end
end
& 在固定装置中:
a_image:
post_id: 1
attachment_file: <%= File.open(Rails.root.join("test/files/test.png")) %>
【讨论】:
【参考方案4】:为了能够使用已上传文件的设备以及在测试中进行上传,我最近使用了 CarrierWave。我写了一个article 来告诉我我会怎么做。
【讨论】:
文件没有永久保存,但我的测试也没有通过。【参考方案5】:我知道它很旧,但是对于一些使用 Rails 5 + RSpec + CarrierWave + Fixtures 的人来说:
编辑测试配置:
# config/initializers/carrierwave.rb
if Rails.env.test?
class NullStorage < CarrierWave::Storage::Abstract
def store!(_file)
_file
end
def retrieve!(identifier)
file = Rails.root.join('spec', 'fixtures', 'files', identifier)
tmp = Rails.root.join('tmp', 'blank_tmp.jpg')
FileUtils.cp(file, tmp)
CarrierWave::SanitizedFile.new(tmp)
end
end
CarrierWave.configure do |config|
config.storage = NullStorage
config.enable_processing = false
end
end
创建文件夹和文件,例如spec/fixtures/files/some-user-photo.jpg
并且,创建一些固定装置,例如:
first_user:
avatar: "some-user-photo.jpg"
name: "First User Name"
about: "First User About Long Text..."
lat: 0.001
lng: 0.001
created_at: <%= Time.current - 3.days %>
updated_at: <%= Time.current - 3.days %>
这足以让测试明白这个用户有一个avatar
【讨论】:
【参考方案6】:我们刚刚删除了所有的固定装置,系统为每个测试播种了这个文件。问问你自己......你需要所有这些装置来进行这个测试吗?不,可能不是。和夹具不要砰!所以我们只使用Model.create!( ... )
和特定数据进行测试
【讨论】:
以上是关于带有载波的 Rails 3 测试夹具?的主要内容,如果未能解决你的问题,请参考以下文章