8

我有一个带有图像属性的 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"]

请问有什么想法吗?是否有我忘记设置的控制器参数?

4

1 回答 1

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

以上是 Carrierwave 文档为 FactoryGirl 测试夹具推荐的设置。它适用于测试模型和大多数控制器动作,但不适用于创建动作。

我的测试日志告诉我,我的图像属性是空白的,尽管传入了这个 File 对象。经过一番搜索,我发现您可以传入 Rack::Test::UploadedFile 的实例(我认为 ActionDispatch::Http::UploadedFile 是通过浏览器提交的内容(?))。

因此,我没有在工厂中将image属性设置为,而是将其设置为. 我的控制器规格已通过,文件上传已保存到数据库中。File.open(...)Rack::Test::UploadedFile.new(Rails.root.join("spec/support/sample.gif"))

我认为这有助于解释为什么很多人在浏览器中见证了成功的文件上传,但在他们的测试或验证中却没有。

这篇关于在 Rails 3 中测试文件附件的帖子确实很有帮助

于 2013-01-09T20:40:47.977 回答