Rails 3 test fixtures with carrierwave?

前端 未结 6 1015
轻奢々
轻奢々 2021-02-05 09:02

I\'m working on upgrading from attachment_fu to carrierwave, since attachment_fu is broken in rails 3.

None of the tests are able to run, because we have invalid fixture

相关标签:
6条回答
  • 2021-02-05 09:29

    Try passing a file instead of a String.

    a_image:
        post_id: 1
        attachment_file: File.open(Rails.root.join("test/files/test.png"))
    

    This works for me using FactoryGirl

    Note: Edit thanks to @dkobozev

    0 讨论(0)
  • 2021-02-05 09:32

    To be able to use fixtures that have uploaded files as well as doing uploads in the tests, I've played around with CarrierWave for a bit lately. I've written an article about how I'd do it.

    0 讨论(0)
  • 2021-02-05 09:32

    We have just removed the fixtures all together, the system seeds this files for each test. Ask yourself... do you need al these fixtures here for this test? No probably not. And Fixtures dont BANG! so we just use Model.create!( ... ) with specific data for the test

    0 讨论(0)
  • 2021-02-05 09:42

    config/initializers/carrier_wave.rb

    In Rails 4

    # class NullStorage is defined here before the following block
    
    if Rails.env.test?
      CarrierWave.configure do |config|
        config.storage NullStorage
      end
    end
    

    & in fixtures:

    a_image:
      post_id: 1
      attachment_file: <%= File.open(Rails.root.join("test/files/test.png")) %>
    
    0 讨论(0)
  • 2021-02-05 09:44

    I know it is old but, for some that uses Rails 5 + RSpec + CarrierWave + Fixtures:

    Edit test configs:

    # 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
    

    Create a folder and a file, for example spec/fixtures/files/some-user-photo.jpg

    and, create some fixtures, for example:

    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 %>
    

    That is enough to make the test understand that this user has an avatar

    0 讨论(0)
  • 2021-02-05 09:47

    The only way I've managed to get this to work is to use a storage provider specifically for testing that doesn't actually save/read files.

    In your config/initializers/carrier_wave.rb Add a NullStorage class that implements the minimum interface for a storage provider.

    # 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
    

    Then when initializing CarrierWave add a clause for the test environment, e.g.,

    if Rails.env.test?
        config.storage NullStorage
    end
    

    Here is a gist of my complete carrier_wave.rb for reference. It also includes how to setup S3 for uploads in staging/production and local storage for development so you can see how to configure CarrierWave in context.

    Once CarrierWave is configured you can simply put any string in the fixtures column to simulate an uploaded file.

    0 讨论(0)
提交回复
热议问题