ruby-on-rails-3 - 使用 RSpec 将参数传递给 Rails Controller 操作中的模拟模型方法的问题

标签 ruby-on-rails-3 mocking rspec-rails

我正在尝试模拟用户模型保存方法以返回 false,并模拟 Controller 在验证失败时会执行的操作。

我的规范如下:

require 'spec_helper'

describe UsersController do
  describe 'POST create_email_user' do
    it 'responds with errors json if saving the model fails' do
      @params = {
        :last_name => 'jones',
        :email => 'asdfasdfasfd@'
      }
      User.stub(:new_email_user) .with(@params) .and_return(@mock_user)

      @mock_user.stub(:save) .and_return(false)

      post :create_email_user, :user => @params, :format => :json

      response.body.should == @mock_user.errors.as_json
      response.status.should == :unprocessable_entity
    end
  end
end

Controller 操作如下所示:

class UsersController < ApplicationController
  def create_email_user
    @user = User.new_email_user(params[:user])
    if @user.save
      # code left out for demo purposes
    else
      render json: @user.errors, status: :unprocessable_entity
    end
  end
end

运行此规范时,我收到错误,基本上表明对 new_email_user 的预期调用得到了错误的参数:

  1) UsersController POST create_email_user responds with errors json if saving the model fails
     Failure/Error: post :create_email_user, :user => @params, :format => :json
       <User(id: integer, email: string, encrypted_password: string, reset_password_token: string, reset_password_sent_at: datetime, remember_created_at: datetime, sign_in_count: integer, current_sign_in_at: datetime, last_sign_in_at: datetime, current_sign_in_ip: string, last_sign_in_ip: string, created_at: datetime, updated_at: datetime, uid: string, provider: string, first_name: string, last_name: string, registration_id: integer, gender: string, authentication_token: string) (class)> received :new_email_user with unexpected arguments
         expected: ({:last_name=>"jones", :email=>"asdfasdfasfd@"})
              got: (["last_name", "jones"], ["email", "asdfasdfasfd@"])
        Please stub a default value first if message might be received with other args as well. 

看来rails将has转换为键值对数组,而我的代码只是在设置中使用直接哈希。

我如何模拟转换为数组,或者我做错了什么?

最佳答案

删除用户的 .with stub ,因为它与测试并不真正相关,而且会导致问题。

如果没有.with, stub 将为任何参数返回该值。 所以:

User.stub(:new_email_user).and_return(@mock_user)

然后我会有一个单独的规范来确保:

User.should_receive(:new_email_user).with(@params)

并在其自己的、狭窄的规范中诊断该问题。

关于ruby-on-rails-3 - 使用 RSpec 将参数传递给 Rails Controller 操作中的模拟模型方法的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14346496/

相关文章:

ruby-on-rails - 使用 RSpec 验证部分参数

Android 测试存储模拟

ruby-on-rails - 我可以在 rspec get/post 上执行 "before hook"

ruby-on-rails - 运行 rake db :create in test environment 时,字符串无法强制转换为整数

ruby-on-rails-3 - 只测试一个它或用 Rspec 描述

ruby-on-rails - rails 3.1 中的 application.js 代码在哪里?

node.js - 模拟 Typeorm QueryBuilder

ruby - 使用预发布 gem 来满足与 Bundler 的传递依赖

ruby-on-rails - 将 ActionDispatch::Http::UploadedFile 上传到 Amazon S3

ruby-on-rails - 如何在 Ruby on Rails 3.1 中禁用 Assets 管道( sprockets )消息的日志记录?