带有载波的 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: &lt;%= File.open(Rails.root.join("test/files/test.png")) %&gt;【参考方案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 测试夹具?的主要内容,如果未能解决你的问题,请参考以下文章

在 Rails 控制台中加载和使用夹具

带有响应方法调用的键的 Rails json

带有加载夹具的 Django 单元测试,用于解决几个相关的应用程序问题

RSpec 中的夹具

Django 不会为某些测试用例重新加载夹具

标记一个 Pytest 夹具而不是使用该夹具的所有测试