【问题标题】:Rails 3 test fixtures with carrierwave?带有载波的 Rails 3 测试夹具?
【发布时间】: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 代替?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 unit-testing fixtures 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!( ... ) 和特定数据进行测试

        【讨论】:

          猜你喜欢
          • 2018-02-21
          • 1970-01-01
          • 1970-01-01
          • 2016-11-01
          • 1970-01-01
          • 2011-06-19
          • 1970-01-01
          • 1970-01-01
          • 2014-06-23
          相关资源
          最近更新 更多