【问题标题】:Rspec error with controller 'create'控制器“创建”的 Rspec 错误
【发布时间】:2011-12-29 05:36:18
【问题描述】:

这是一个 comm_logs 控制器“创建”

  def create
    if has_create_right?
      @customer = Customer.find(params[:customer_id])
      @comm_log = @customer.comm_log.new(params[:comm_log], :as => :roles_new)
      @comm_log.input_by_id = session[:user_id]
      if @comm_log.save
        #send out email
        redirect_to URI.escape("/view_handler?index=0&msg=Log saved!")
      else
        flash.now[:error] = "can't save log!"
        render 'new'
      end     
    else
      redirect_to URI.escape("/view_handler?index=0&msg=insufficient rights!")    
    end
  end

rspec 代码为:

  describe "'create'" do
    it "should be successful for sales member" do
      session[:sales] = true
      session[:user_id] = 1
      session[:member] = true
      customer = Factory(:customer)
      log = Factory(:comm_log, :customer_id => customer.id)      
      get 'create', :customer_id => customer.id, :comm_log => log
      response.should redirect_to URI.escape("/view_handler?index=0&msg=Log saved!")
    end
  end

这是 rspec 错误:

  1) CommLogsController 'create' should be successful for sales member
     Failure/Error: get 'create', :customer_id => customer.id, :comm_log => log
     NoMethodError:
       undefined method `stringify_keys' for "1":String
     # c:in `build'
     # ./app/controllers/comm_logs_controller.rb:30:in `create'
     # ./spec/controllers/comm_logs_controller_spec.rb:79:in `block (3 levels) in <top (required)>'

完全相同的代码(控制器和 rspec)适用于另一个类似的控制器。

对这个问题有什么想法吗?谢谢。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3.1 rspec2


    【解决方案1】:

    这行是罪魁祸首:

          get 'create', :customer_id => customer.id, :comm_log => log
    

    您正在尝试将实际的 activerecord 实例填充到 params 哈希中。 Rails 知道参数不能是这样的对象,因此它会发送 id。然后,您尝试使用该 id,就好像它是一个哈希一样,这显然是行不通的。

    而是传递实际提交的内容:用于创建对象的哈希值。你可能会发现工厂女孩的attributes_for 方法很有用。

    顺便说一句,能够“获得”一个创建动作是很奇怪的。

    【讨论】:

    • 在 rspec 中添加 attributes_for 解决了这个问题。多么愚蠢的错误。谢谢!
    【解决方案2】:

    create 方法中,new action 期望获得一个属性散列并将其字符串化为列名的键。

    替换
    @comm_log = @customer.comm_log.new(params[:comm_log], :as =&gt; :roles_new)

    @comm_log = @customer.comm_log.new(:comm_log =&gt; params[:comm_log], :as =&gt; :roles_new) 或者因为它适合您的相应模型的列名。

    【讨论】:

    • 在控制器中添加苛刻的 :comm_log => parmas[:comm_log] 可消除错误(NoMethodError ...)。但是 rspec 代码没有通过。它返回 200 而不是 redirect_to 页面。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多