【问题标题】:Rspec controller test for callback after_saveRspec 控制器测试回调 after_save
【发布时间】:2014-12-19 20:26:50
【问题描述】:

我正在尝试测试发布到我的控制器中的 create 方法是否会触发我使用 after_save 定义的回调

这是发布到的控制器方法

def create
@guest = Guest.new(guest_params)
@hotel = Hotel.find(visit_params[:hotel_id])

#set visit local times to UTC
@visit= Visit.new(visit_params)
@visit.checked_out_at = (DateTime.now.utc + visit_params[:checked_out_at].to_i.to_i.days).change(hour: @visit.hotel.checkout_time.hour)
@visit.checked_in_at = Time.now.utc
#@visit.user_id = current_user.id
@self_serve = (params[:self_serve] && params[:self_serve] == "true")
if @guest.save
  @visit.guest_id = @guest.id
  if @visit.save
    if @self_serve
      flash[:notice] = "#{@visit.guest.name}, you have successfully checked in!."
      redirect_to guest_checkin_hotel_path(@visit.hotel)
    else
      flash[:notice] = "You have successfully checked in #{@visit.guest.name}."
      redirect_to hotel_path(@visit.hotel)
    end
  else
    render "new"
  end
else
  render "new"
end
end

这是我的 spec/controllers/guests_controller_spec.rb 测试失败

RSpec.describe GuestsController, :type => :controller do
describe "#create" do
    let!(:params) do { name: "John Smith", mobile_number: "9095551234" } end
    context "when new guest is saved" do
        it "triggers create_check_in_messages callback" do
            post :create, params
            expect(response).to receive(:create_check_in_messages)
        end
    end
end
end

这是我的模型/关注点/visit_message.rb 回调文件

module VisitMessage
  extend ActiveSupport::Concern

  included do
    after_save :create_check_in_messages
  end

  def create_check_in_messages
   . . .
  end
end

这是我运行 'rspec spec/controllers/guests_controller_spec.rb' 时的失败消息

1) GuestsController#create when new guest is saved triggers create_check_in_messages callback
 Failure/Error: post :create, params
 ActionController::ParameterMissing:
   param is missing or the value is empty: guest
 # ./app/controllers/guests_controller.rb:63:in `guest_params'
 # ./app/controllers/guests_controller.rb:10:in `create'
 # ./spec/controllers/guests_controller_spec.rb:36:in `block (4 levels) in <top (required)>'

我一直在搜索stackoverflow,但没有运气。感谢您的帮助!

【问题讨论】:

    标签: ruby-on-rails post rspec callback controllers


    【解决方案1】:

    我假设控制器中的guest_params 方法如下所示:

    def guest_params
        params.require(:guest).permit(....)
    end
    

    如果是这种情况,您需要更新测试用例中的 POST 调用:

    post :create, {guest: params}
    

    附带说明,您的控制器不必要地臃肿。我会阅读有关使用相关模型来简化代码的内容,特别是使用accepts_nested_attributes_for

    http://guides.rubyonrails.org/association_basics.html#detailed-association-reference http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

    【讨论】:

    • 您的假设是正确的,我已经进行了调整。谢谢!但是,它对我来说仍然失败。 'expect(response).to receive(:create_check_in_messages)' 是测试回调被触发的正确语法吗?
    • 嗯,首先,您应该在 ModelSpec 上测试它,而不是在 ControllerSpec 上测试,因为它是特定于模型的操作,所以这可能是问题所在。我相信receive 是正确的评估者,但老实说,我通常通过检查数据操作过程是否实际发生来测试回调。另外,仅供参考,您确实意识到通过使用after_save,该回调将在创建和更新时触发?
    • 感谢您指出这些缺陷。我会进行调整并尝试数据处理路线。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多