2012-06-03 17 views
6

Tôi khá mới để thử nghiệm và có một UsersController mà tôi muốn kiểm tra. Tôi bắt đầu với hành động mới và cho đến nay có những điều sau đây;Làm cách nào để kiểm tra việc gán một biến mẫu trong hành động mới của trình điều khiển của tôi với rspec?

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 tôi cho đến nay trông như thế này

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

tôi mong đợi thử nghiệm đầu tiên của tôi để làm việc nhưng khi tôi chạy nó tôi nhận được như sau;

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

Phát xung quanh trong bảng điều khiển cho thấy những điều sau đây;

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 

Vì vậy, bây giờ tôi tò mò là tại sao 2 đối tượng ActiveRecord trống không bằng nhau (sau khi tất cả, Array.new == Array.new trả về true), và những gì tôi phải làm gì để vượt qua thử nghiệm của tôi.

Trả lời

6

Bạn có lẽ nên thay đổi thử nghiệm của bạn để một cái gì đó như thế này:

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 

Và bạn sẽ có tác dụng tương tự. Nếu hai đối tượng không được lưu, chúng không có khóa chính cho Rails sẽ sử dụng đối tượng object_id để so sánh chúng, đó là lý do tại sao chúng không phải là ==.

+2

Nếu tác giả muốn kiểm tra nếu một bản ghi là cả hai mới và không có bất kỳ thuộc tính được thiết lập, ông cũng sẽ cần một kiểm tra cho 'should_not be_changed '. – jdoe

+0

Tuyệt vời! Không biết về điều này. –

+1

Cảm ơn vì điều đó. Điều đó có ý nghĩa tốt. – brad

1

Tính tương đương của Activerecord chủ yếu là về việc liệu hai đối tượng có tương ứng với cùng một hàng cơ sở dữ liệu hay không (ví dụ hai trường hợp tương ứng với cùng một hàng bằng nhau, ngay cả khi bạn bắt đầu thay đổi các thuộc tính của một trong số chúng).

Nếu bạn gọi User.new hai lần và lưu từng đối tượng, bạn sẽ kết thúc với 2 hàng riêng biệt trong cơ sở dữ liệu. Với tôi, điều đó có nghĩa là họ không nên bình đẳng.

Xét về thử nghiệm, bạn có thể làm 2 việc. Một là để kiểm tra xem người dùng được chỉ định có phải là một người dùng hay không và nó chưa được lưu.

Một cách khác là một cái gì đó dọc theo dòng của

User.should_receive(:new).and_return(@user) 
get :new 
assigns(:user).should == @user 
+0

oops - cũng được phát hiện! –

Các vấn đề liên quan