如何使用rspec在我的控制器的新操作中测试实例变量的赋值?

bra*_*rad 6 ruby testing rspec ruby-on-rails ruby-on-rails-3

我是一个相当新的测试,并有一个我想测试的UsersController.我从新行动开始,到目前为止有以下几点;

require 'spec_helper'

describe UsersController do

  describe "GET 'new'" do
    it "assigns a new User to @user" do
      user = User.new
      get :new
      assigns(:user).should eq(user)
    end
    it "renders the :new template"
  end

end
Run Code Online (Sandbox Code Playgroud)

到目前为止,我的UsersController看起来像这样

class UsersController < ApplicationController
  def new
    @user = User.new
  end
end
Run Code Online (Sandbox Code Playgroud)

我期待我的第一次测试工作,但是当我运行它时,我得到以下内容;

Failures:

  1) UsersController GET 'new' assigns a new User to @user
     Failure/Error: assigns(:user).should eq(user)

       expected: #<User id: nil, email: nil, username: nil, password_digest: nil, created_at: nil, updated_at: nil>
            got: #<User id: nil, email: nil, username: nil, password_digest: nil, created_at: nil, updated_at: nil>

       (compared using ==)

       Diff:#<User:0x007fe4bbfceed0>.==(#<User:0x007fe4bce5c290>) returned false even though the diff between #<User:0x007fe4bbfceed0> and #<User:0x007fe4bce5c290> is empty. Check the implementation of #<User:0x007fe4bbfceed0>.==.
     # ./spec/controllers/users_controller_spec.rb:9:in `block (3 levels) in <top (required)>'
Run Code Online (Sandbox Code Playgroud)

在控制台中玩游戏揭示了以下内容;

irb(main):001:0> a = User.new
=> #<User id: nil, email: nil, username: nil, password_digest: nil, created_at: nil, updated_at: nil>
irb(main):002:0> b = User.new
=> #<User id: nil, email: nil, username: nil, password_digest: nil, created_at: nil, updated_at: nil>
irb(main):003:0> a == b
=> false
Run Code Online (Sandbox Code Playgroud)

所以现在我很好奇为什么2个空的ActiveRecord对象不相等(毕竟,Array.new == Array.new返回true),以及我必须做些什么来让我的测试通过.

Mau*_*res 6

您可能应该将测试更改为以下内容:

describe UsersController do

  describe "GET 'new'" do
    it "assigns a new User to @user" do
      get :new
      assigns(:user).should be_new_record
      assigns(:user).kind_of?(User).should be_true
    end
    it "renders the :new template"   end

end
Run Code Online (Sandbox Code Playgroud)

你会有同样的效果.如果没有保存两个对象,它们没有Rails的主键将使用object_id相等来比较它们,这就是为什么它们不是==.

  • 如果作者想要检查记录是否都是新的并且没有设置任何属性,他还需要检查一个`should_not be_changed`. (2认同)