如何测试文件是否在控制器中上传?

Gre*_*ass 18 rspec uploader carrierwave ruby-on-rails-4 factory-bot

我正在尝试在上传图片时测试我的用户是否有照片值.它在浏览器中工作正常,测试的基本功能通过,但如果我试图断言user.photo不是nil,它就会失败.这是测试

describe 'POST #update' do
  context 'when there is an image' do
    it 'renders the crop template' do
      login(user)
      photo = File.open(File.join(Rails.root, '/spec/fixtures/images/bob-weir.jpg'))
      post :update, user: { photo: photo }

      expect(response).to render_template('crop')
      user.reload
      expect(user.photo.file).to_not be_nil
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

正在生产:

Failure/Error: expect(user.photo.file).to_not be_nil
       expected: not nil
            got: nil
Run Code Online (Sandbox Code Playgroud)

如果我在测试结束时调试器并执行user.photo,我会得到:

(byebug) user.photo

#<PhotoUploader:0x007fa447029480 @model=#<User id: 226, ..... photo: nil>,
@mounted_as=:photo, @storage=#<CarrierWave::Storage::File:0x007fa4468ddbb8 
@uploader=#<PhotoUploader:0x007fa447029480 ...>>>
Run Code Online (Sandbox Code Playgroud)

有没有办法确保控制器实际上在数据库中保存了照片值?它只是模型的一个属性,它将文件名保存为字符串.

Gre*_*ass 29

答案是使用fixture_file_upload:http://api.rubyonrails.org/classes/ActionDispatch/TestProcess.html#method-i-fixture_file_upload

post :update, user: { photo: fixture_file_upload('images/bob-weir.jpg', 'image/jpg') }
Run Code Online (Sandbox Code Playgroud)

此外,如果您想在工厂中使用它,它将是:

Rack::Test::UploadedFile.new(File.open(File.join(Rails.root, '/spec/fixtures/images/bob-weir.jpg')))
Run Code Online (Sandbox Code Playgroud)