简体   繁体   English

在Rails中使用RSpec测试create Action

[英]Testing create Action using RSpec in Rails

I am using RSpec to test my controller actions and have been successfully tested my index , show , edit actions so far. 我正在使用RSpec测试我的控制器动作,并且到目前为止已经成功测试了我的indexshowedit动作。 But for create action it is giving me the following error for valid attributes. 但是对于create操作,它给我以下有关有效属性的错误。 I'm using rails 5 and ruby 2.5.3. 我正在使用rails 5和ruby 2.5.3。 Can't understand what am I doing wrong. 无法理解我在做什么错。

file /spec/factories/leaves.rb 文件/spec/factories/leaves.rb

FactoryBot.define do
  factory :leave do
    id {Faker::Number.between(from = 1, to = 3)}
    user_id {Faker::Number.between(from = 1, to = 3)}
    team_lead_id {Faker::Number.between(from = 1, to = 3)}
    fiscal_year_id {Faker::Number.between(from = 1, to = 3)}
    start_day {Date.today - Faker::Number.number(3).to_i.days}
    end_day {Date.today - Faker::Number.number(3).to_i.days}
    reason {Faker::Lorem.sentences(sentence_count = 3, supplemental = false)}
    status {Faker::Number.between(from = 1, to = 3)}

    factory :invalid_leave do
      user_id nil
    end
  end
end

file /spec/controllers/leave_controller_spec.rb 文件/spec/controllers/leave_controller_spec.rb

context 'with valid attributes' do
  it 'saves the new leave in the database' do
    leave_params = FactoryBot.attributes_for(:leave)
    expect{ post :create, params: {leave: leave_params}}.to change(Leave,:count).by(1)
  end
  it 'redirects to leave#index' do
    render_template :index
  end
end

file /app/controller/leave_controller.rb 文件/app/controller/leave_controller.rb

def create
    @leave = Leave.new(leave_params)

    if @leave.save
      flash[:notice] = t('leave.leave_create')
      redirect_to leave_index_path
    else
      flash[:notice] = t('leave.leave_create_error')
      redirect_to leave_index_path
    end

  end

The error is: 错误是:

LeaveController POST#create with valid attributes saves the new leave in the database
     Failure/Error: expect{ post :create, params: {leave: leave_params}}.to change(Leave,:count).by(1)
       expected `Leave.count` to have changed by 1, but was changed by 0
     # ./spec/controllers/leave_controller_spec.rb:64:in `block (4 levels) in <top (required)>'

Update Leave Database 更新请假数据库

create_table "leaves", force: :cascade do |t|
    t.integer "user_id", null: false
    t.integer "team_lead_id", null: false
    t.integer "fiscal_year_id", null: false
    t.date "start_day", null: false
    t.date "end_day", null: false
    t.text "reason", null: false
    t.integer "status", null: false
    t.string "comment"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

Leave Model 离开模型

class Leave < ApplicationRecord
    validates :user_id, :team_lead_id, :fiscal_year_id, :start_day, :end_day, :reason, :status, presence: true
    end

I think that might be because of id which you set in factory. 我认为这可能是因为您在工厂设置的id You shouldn't set id attribute in factory. 您不应在工厂中设置id属性。 That's why number of Leave objects didn't change. 因此, Leave对象的数量没有变化。

Additionally, I assume that you have some relations there - user_id , team_lead_id etc. If these relations are necessarry to create leave object then you have to create factories for these models, too. 此外,我认为你有一些关系,有- user_idteam_lead_id等。如果这些关系necessarry创建假的对象,那么你必须为这些车型的工厂了。

In the end your factory should look like this 最后,您的工厂应该看起来像这样

FactoryBot.define do
  factory :leave do
    user
    team_lead
    fiscal_year
    start_day {Date.today - Faker::Number.number(3).to_i.days}
    end_day {Date.today - Faker::Number.number(3).to_i.days}
    reason {Faker::Lorem.sentences(sentence_count = 3, supplemental = false)}
    status {Faker::Number.between(from = 1, to = 3)}

    factory :invalid_leave do
      user nil
    end
  end
end

Reference: Factory Bot documentation - associations 参考: Factory Bot文档-关联

[For Future Reader] I got it to work by doing the fooling in leave_controller_spec.rb file. [面向未来读者]我通过在Leave_controller_spec.rb文件中进行愚弄而使其工作。

 describe 'POST#create' do

    context 'with valid attributes' do
      let(:valid_attribute) do
        attributes_for(:leave,
                      user_id: 2,
                      team_lead_id: 3,
                      fiscal_year_id: 2,
                      start_day: '2018-10-10'.to_date,
                      end_day: '2018-10-10'.to_date,
                      reason: 'Sick',
                      status: 2)
      end

      it 'saves the new leave in the database' do

        expect do
          post :create, params: {leave: valid_attribute}
        end.to change(Leave,:count).by(1)
      end
      it 'redirects to leave#index' do
        render_template :index
      end
    end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM