Rspec控制器"创建"格式:: js时动作成功但格式:: html时失败

时间:2014-07-15 08:14:39

标签: ruby-on-rails rspec carrierwave

我得到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

2 个答案:

答案 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