【问题标题】:Not getting the exact output when testing Create action in RSpec在 RSpec 中测试创建操作时没有得到准确的输出
【发布时间】:2016-11-18 11:55:09
【问题描述】:

我正在使用模拟和存根进行测试,但在控制器中测试 create 操作时无法获得所需的输出。

失败的测试:

describe 'authenticated user' do
  let(:user) { instance_double(User) }
  before do
    allow(controller).to receive(:current_user) { user }
    allow(controller).to receive(:authenticate_user!) { true }
  end

  describe "POST create" do
    let(:achievement_params) { { title: "title" } }
    let(:create_achievement) { instance_double(CreateAchievement) }

    before do
      allow(CreateAchievement).to receive(:new) { create_achievement }
    end

    it 'sends create message to CreateAchievement' do
    expect(CreateAchievement).to receive(:new).with(achievement_params, user)
    expect(create_achievement).to receive(:create)
    post :create, achievement: achievement_params

    end
  end
end

控制器中的create 操作

def create
  service = CreateAchievement.new(params[:achievement], current_user)
  service.create
  render nothing: true
end

错误:

  1) AchievementsController authenticated user POST create sends create message to CreateAchivement
 Failure/Error: expect(CreateAchievement).to receive(:new).with(achievement_params, user)

   #<CreateAchievement (class)> received :new with unexpected arguments
     expected: ({:title=>"title"}, #<InstanceDouble(User) (anonymous)>)
          got: (<ActionController::Parameters {"title"=>"title"} permitted: false>, #<InstanceDouble(User) (anonymous)>)
   Diff:
   @@ -1,2 +1,3 @@
   -[{:title=>"title"}, #<InstanceDouble(User) (anonymous)>]
   +[<ActionController::Parameters {"title"=>"title"} permitted: false>,
   + #<InstanceDouble(User) (anonymous)>]

【问题讨论】:

    标签: ruby-on-rails rspec stub rspec-mocks


    【解决方案1】:

    那是因为您需要在控制器中“允许”您的 POST 值:

    def achievement_params
      params.require(:achievement).permit(:title)
    end
    

    然后,从您的控制器操作中调用它:

    service = CreateAchievement.new(achievement_params, current_user)
    

    【讨论】:

      【解决方案2】:

      您需要允许控制器中的参数:

      private
      
      def achievement_params
         params.require(:achievement).permit(:title)
      end
      

      更改您的创建方法以接收这些参数,而不是 params[:achievement]

      def create
        service = CreateAchievement.new(achievement_params, current_user)
        service.create
        render body: nil
      end
      

      在您的规范中,您需要使用允许title 参数的ActionController::Parameters.new 方法创建参数:

      let(:achievement_params) { ActionController::Parameters.new('title': 'title').permit(:title) }
      

      如下:

      describe 'POST create' do
        let(:achievement_params) { ActionController::Parameters.new('title': 'title').permit(:title) }
        let(:create_achievement) {instance_double(CreateAchievement)}
      
        before do
          allow(CreateAchievement).to receive(:new) {create_achievement}
        end
      
        it 'sends create message to CreateAchievement' do
          expect(CreateAchievement).to receive(:new).with(achievement_params, user)
          expect(create_achievement).to receive(:create)
      
          post :create, params: {achievement: achievement_params }
        end
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-06-28
        • 1970-01-01
        • 1970-01-01
        • 2013-05-06
        • 2020-04-28
        • 2017-01-03
        相关资源
        最近更新 更多