我有一个带有图像属性的Artwork模型,其中安装了Carrierwave。在编写控制器规范时,我意识到图像字段保持空白,即使我认为我传入的是文件对象。
我的调试信息告诉我问题在于我安装了CarrierWave的图像属性,而不是其他东西。我不认为我传递了它需要的信息,但我不知道该尝试什么。
这是控制器操作,带有一些调试信息来识别问题:
def create
@artwork = @imageable.artworks.new(params[:artwork])
logger.debug "Artwork should be valid: #{@artwork.valid?}"
logger.debug "Errors: #{@artwork.errors.full_messages}"
if @artwork.save
flash[:success] = "Artwork created."
redirect_to [@imageable, :artworks]
else
flash[:error] = "Artwork not created."
render :new
end
end
在测试日志中,我在运行我的规范后看到了这个:
Processing by ArtworksController#create as HTML
Parameters: {"artwork"=>{"image"=>"#<File:0x4515480>", "title"=>"Portrait","year"=>"2012", "surface_type"=>"canvas", "size"=>"10 x 10", "price"=>"100.0", "for_sale"=>false, "prints_available"=>false, "notes"=>"extra notes"}, "file"=>"#<File:0x46c6938>", "originals_gallery_id"=>"1"}
[1m[36mOriginalsGallery Load (0.0ms)[0m [1mSELECT "originals_galleries".* FROM "originals_galleries" WHERE "originals_galleries"."id" = ? LIMIT 1[0m [["id", "1"]]
Artwork should be valid: false
Errors: ["Image can't be blank"]
请问有什么想法吗?是否有控制器参数我忘了设置?
答案 0 :(得分:18)
我的问题是一个更普遍的问题:在我的测试期间(使用Rspec和FactoryGirl)我将错误的文件对象传递给控制器操作。这是我为图像属性定义的一种对象:
FactoryGirl.define do
factory :artwork do
image { File.open(File.join(Rails.root, 'spec', 'support', 'sample.gif')) }
...other attributes omitted
end
end
The above is the setup that Carrierwave docs recommended for FactoryGirl test fixtures.它适用于测试模型和大多数控制器操作,但不适用于创建操作。
我的测试日志告诉我我的图片属性是空白的,尽管传入了这个File对象。经过一些搜索,我发现你可以传入一个Rack :: Test :: UploadedFile的实例(我认为ActionDispatch :: Http :: UploadedFile是通过浏览器提交的内容(?))。
因此,我在工厂中将image
属性设置为File.open(...)
,而不是Rack::Test::UploadedFile.new(Rails.root.join("spec/support/sample.gif"))
设置为{{1}}。我的控制器规范已通过,文件上传已保存到数据库中。
我认为这有助于解释为什么许多人在浏览器中看到成功上传文件,但在测试或验证中没有。
This post about testing file attachments in Rails 3 really helped