【问题标题】:Rails carrierwave testing - how to remove file after test?Rails 载波测试 - 测试后如何删除文件?
【发布时间】:2018-08-12 01:47:08
【问题描述】:

我正在使用 rspec 和 capybara 测试载波上传功能。我有类似的东西:

describe "attachment" do
    let(:local_path)  { "my/file/path" }
    before do
      attach_file('Attachment file', local_path)
      click_button "Save changes"       
    end

    specify {user.attachment.should_not be_nil}
    it { should have_link('attachment', href: user.attachment_url) }
end

这很好用。问题是在测试上传的图像后仍然在我的 public/uploads 目录中。测试完成后如何删除它?我试过这样的事情:

after do
   user.remove_attachment!
end

但它不起作用。

【问题讨论】:

    标签: ruby-on-rails rspec capybara carrierwave


    【解决方案1】:

    您不是唯一一个在删除carrierwave 中的文件时遇到问题的人。

    我最终做了:

    user.remove_attachment = true
    user.save
    

    我收到了这个提示reading this

    【讨论】:

    • 谢谢。现在好多了,虽然还不够完美。该文件确实已删除,但存储它的目录(在本例中为 public/uploads/user/attachment/871)仍然存在。你认为你也可以删除它吗?
    • 为了解决这个问题,我创建了一个专用文件夹来上传测试环境中的文件并刷新它。
    • 我遇到了同样的问题,并通过将以下内容添加到我的模型中,用更少的行解决了它: before_destroy :remove_attachment!
    • @apneadiving 只是为了确认一下,这个脚本user.remove_attachment = true 你把它放在app/controllers/your-controller.rb 里面了吗?另外,当您说“在测试环境中上传文件的专用文件夹”时,您的意思是def store_dir File.join( 'public', 'uploads', Rails.env, model.class.table_name.to_s, mounted_as.to_s, model.id.to_s ) end,对吗?但是“冲洗”是什么意思?
    【解决方案2】:

    spec/support/carrierwave.rb 中似乎对我有用的更清洁的解决方案如下:

    uploads_test_path = Rails.root.join('uploads_test')
    
    CarrierWave.configure do |config|
      config.root = uploads_test_path
    end
    
    RSpec.configure do |config|
      config.after(:suite) do
        FileUtils.rm_rf(Dir[uploads_test_path])
      end
    end
    

    这会将整个根文件夹设置为特定于测试环境并在套件之后将其全部删除,因此您不必分别担心store_dircache_dir

    【讨论】:

      【解决方案3】:

      哈!我今天找到了答案。

      下载文件的自动删除是在 after_commit 挂钩中完成的。 默认情况下,这些不会在 rails 测试中运行。我从来没有想过。

      然而,这里的附注中随意地记录了它: http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html#method-i-after_commit

      我通过深入研究载波代码发现了这一点 调试器,只是碰巧在上面的 cmets 中注意到它 源代码到 after_commit 当我介入时。

      谢天谢地,ruby 库不会像 JS 那样在运行时去除 cmets。 ;)

      文档中建议的解决方法是包含 'test_after_commit' 宝石在您的 Gemfile 中,但仅在测试环境中。

      宝石文件:

      ...
      gem 'test_after_commit', :group => :test
      ...
      

      当我这样做时,它完全解决了我的问题。

      现在,我的销毁后清理断言通过了。

      【讨论】:

        【解决方案4】:

        此技术的latest CarrierWave documentation 如下:

        config.after(:suite) do
          if Rails.env.test? 
            FileUtils.rm_rf(Dir["#{Rails.root}/spec/support/uploads"])
          end 
        end
        

        请注意,以上只是假设您对图像使用spec/support/uploads/,并且您不介意删除该目录中的所有内容。如果每个上传器的位置不同,您可能希望直接从(工厂)模型派生上传和缓存目录:

        config.after(:suite) do
          # Get rid of the linked images
          if Rails.env.test? || Rails.env.cucumber?
            tmp = Factory(:brand)
            store_path = File.dirname(File.dirname(tmp.logo.url))
            temp_path = tmp.logo.cache_dir
            FileUtils.rm_rf(Dir["#{Rails.root}/public/#{store_path}/[^.]*"])
            FileUtils.rm_rf(Dir["#{temp_path}/[^.]*"])
          end
        end
        

        或者,如果您想删除在初始化程序中设置的 CarrierWave 根目录下的所有内容,您可以这样做:

        config.after(:suite) do
          # Get rid of the linked images
          if Rails.env.test? || Rails.env.cucumber?
            FileUtils.rm_rf(CarrierWave::Uploader::Base.root)
          end
        end
        

        【讨论】:

          猜你喜欢
          • 2018-02-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-11-09
          • 2021-11-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多