RSpec控制器测试:需要测试Has_Many嵌套资源

时间:2014-01-28 11:25:06

标签: ruby-on-rails rspec ruby-on-rails-4 factory-bot

我有2个型号:

class Item < ActiveRecord::Base
...
    validates :pictures, length:{minimum:1, maximum:10}
    has_many :pictures
end

class Picture < ActiveRecord::Base
  belongs_to :item
  mount_uploader :path, PictureUploader
  validates_associated :item
end

使用FactoryGirl的这个Item and Picture工厂

FactoryGirl.define do
  factory :item do
    name "Item 1"
    ad_type "for_sale"
    description Faker::Lorem.sentence(10)
    category
    user
    price "99.99"
    phone Faker::PhoneNumber.phone_number
    pictures {[FactoryGirl.create(:picture)]}
  end
end

FactoryGirl.define do
  factory :picture do
    path "image_url"
  end
end

如果我要求创建项目

上至少有1张图片,则这些控制器测试失败
describe 'with valid params' do
      it 'creates a new Item' do
        expect{
          post :create, {:item => valid_attributes, user_id:@user.id}
        }.to change(Item, :count).by(1)
      end

      it 'assigns a newly created as @item' do
        post :create, {:item => valid_attributes, :user_id => @user.id}
        expect(assigns(:item)).to be_a(Item)
        expect(assigns(:item)).to be_persisted
      end

      it 'redirects to the created item' do
        post :create, {:item => valid_attributes, :user_id => @user.id}
        expect(response).to redirect_to([@user, Item.last])
      end
    end

它失败并显示消息:

1) ItemsController POST create with valid params creates a new Item
     Failure/Error: expect{
       count should have been changed by 1, but was changed by 0
     # ./spec/controllers/items_controller_spec.rb:36:in `block (4 levels) in <top (required)>'

  2) ItemsController POST create with valid params assigns a newly created as @item
     Failure/Error: expect(assigns(:item)).to be_persisted
       expected persisted? to return true, got false
     # ./spec/controllers/items_controller_spec.rb:44:in `block (4 levels) in <top (required)>'

  3) ItemsController POST create with valid params redirects to the created item
     Failure/Error: expect(response).to redirect_to([@user, Item.last])
       Expected response to be a <redirect>, but was <200>
     # ./spec/controllers/items_controller_spec.rb:49:in `block (4 levels) in <top (required)>'

如果我不需要至少1张图片(删除项目图片的最小长度验证),则测试通过。我想知道如何重写post :create行以传递图片。

如何使用带有rspec的post :create子句创建带有图片的项目?或者我应该在工厂里做这件事?

谢谢!

更新

这是来自Items控件的更新和创建操作

def create
    @item = Item.new(item_params)

    respond_to do |format|
      if @item.save
        format.html { redirect_to [current_user, @item], notice: 'Item was successfully created.' }
        format.json { render action: 'show', status: :created, location: @item }
      else
        format.html { render action: 'new' }
        format.json { render json: @item.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /items/1
  # PATCH/PUT /items/1.json
  def update
    respond_to do |format|
      if @item.update(item_params)
        format.html { redirect_to user_item_path(current_user, @item), notice: 'Item was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @item.errors, status: :unprocessable_entity }
      end
    end
  end

0 个答案:

没有答案