我得到ProductsController
,我正在type: :controller
规范中进行测试。我的测试在format: :js
时通过,但在format: :html
时失败。同样在开发环境中,我成功地在html和js中执行相同的操作。
规范使用有效参数对创建操作进行简单POST,并声明创建了记录。
特殊性是Product
模型has_many ProductImage
,而ProductImage
使用CarrierWave来处理文件上传。
这是我的规范
describe 'POST create' do
[:html, :js].each do |format|
context "as #{format}" do
let(:valid_create_attributes) { {
name: 'name', description: 'description', link: 'http://web.site/page',
product_images_attributes: [{image: fixture_image('product.png')}]
} }
before { post :create, format: format,
product: valid_create_attributes }
it { expect(Product.count).to eq(1) }
end
end
end
该测试在format: :js
时通过,但在format: :html
失败时通过。我查看了模型验证错误,它显示了{:"product_images.image"=>[:blank]}
所以我在规范期间检查控制器日志,我发现了无法解释的差异
Processing by ProductsController#create as HTML
Parameters: { "product"=>{"name"=>"name", "description"=>"description", "link"=>"http://web.site/page",
"product_images_attributes"=>[{"image"=>"#<File:0x007ffe7ab41628>"}]}}
Processing by ProductsController#create as JS
Parameters: { "product"=>{"name"=>"name", "description"=>"description", "link"=>"http://web.site/page",
"product_images_attributes"=>[{"image"=>#<File:/workspace/my_project/spec/support/image_fixtures/product.png>}]}}
如果你仔细查看product_images_attributes
收到的参数,你可以看到在:html
测试中文件对象没有输出文件路径,当在:js
文件似乎是正确地附上了。
在我的控制器中添加pp @product.product_images.first.image.file
,确认在:html
案例中,文件为零
我试过了:
:js
,仅运行:html
sleep 3
(我甚至不知道为什么会这样做)任何想法都将不胜感激!
顺便说一下,你可能想知道fixture_image
。这是来源:
def fixture_image(image)
File.new fixture_image_path(image)
end
def fixture_image_path(image)
File.join(Rails.root, 'spec', 'support', 'image_fixtures', image)
end
答案 0 :(得分:1)
表单中的真正多部分: 像
<%= form_tag({:action => :upload}, :multipart => true) do %>
<%= file_field_tag 'picture' %>
<% end %>
<%= form_for @person do |f| %>
<%= f.file_field :picture %>
<% end %>
答案 1 :(得分:0)
@ vikram的回答让我朝着正确的方向前进。
要在rspec中上传文件,您不能像我一样发送File
对象,您必须使用Rack::Test::UploadedFile
对象。
def fixture_image(image, mime: 'image/png')
Rack::Test::UploadedFile.new fixture_image_path(image), mime
end