6

私はテストにかなり慣れておらず、テストしたい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

これまでの私のUsersControllerは次のようになります

class UsersController < ApplicationController
  def new
    @user = User.new
  end
end

最初のテストが機能することを期待していましたが、実行すると次のようになります。

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)>'

コンソールで遊んでみると、次のことがわかります。

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

だから今、私は2つの空のActiveRecordオブジェクトが等しくない理由(結局のところ、Array.new == Array.newtrueを返す)と、テストに合格するために何をしなければならないのかについて興味があります。

4

2 に答える 2

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

そして、あなたは同じ効果を持つでしょう。2つのオブジェクトが保存されていない場合、それらのオブジェクトには主キーがありません。Railsはobject_idの等式を使用してそれらを比較するため、==ではありません。

于 2012-06-03T13:31:53.227 に答える
1

Activerecord の同等性は、主に 2 つのオブジェクトが同じデータベース行に対応するかどうかに関するものです (たとえば、同じ行に対応する 2 つのインスタンスは、そのうちの 1 つの属性を変更し始めても同等です)。

2 回呼び出しUser.newて各オブジェクトを保存すると、データベースに 2 つの異なる行が作成されます。したがって、私には、それらが平等であってはならないことは理にかなっています。

テストに関しては、2 つのことを実行できます。1 つは、割り当てられたユーザーがユーザーであり、保存されていないことを確認することです。

別の方法は、

User.should_receive(:new).and_return(@user)
get :new
assigns(:user).should == @user
于 2012-06-03T13:37:38.800 に答える