Rails载波测试 – 如何在测试后删除文件?

我正在使用rspec和capybara测试carrierwave上传function。 我有类似的东西:

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 

但它不起作用。

你不是唯一一个在carrierwave中删除文件的问题。

我最终做了:

 user.remove_attachment = true user.save 

我得到了这个提示。

哈! 我今天找到了答案。

下载文件的自动删除是在after_commit挂钩中完成的。 这些在rails测试中默认不运行。 我永远不会猜到这一点。

然而,在这里的附言中没有记录它: http : //api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html#method-i-after_commit

我通过深入研究带有调试器的carrierwave代码发现了这一点,当我进入它时,恰好在源代码上面的注释中注意到after_commit。

谢天谢地ruby库在运行时没有像JS一样被剥夺注释。 ;)

文档中建议的解决方法是在Gemfile中包含‘test_after_commit’gem ,但仅限于测试环境中。

的Gemfile:

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

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

现在,我的破坏后的清理断言通过了。

该技术的最新CarrierWave文档如下:

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

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

 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 

一个似乎对我spec/support/carrierwave.rb的清洁解决方案是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