2012-06-03 6 views
6

Sono abbastanza nuovo da testare e ho un controller utenti che voglio testare. Sto iniziando con la nuova azione e finora ho il seguente;Come si verifica l'assegnazione di una variabile di istanza nella nuova azione del mio controller con 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 

mio UsersController sembra così lontano come questo

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

mi aspettavo il mio primo test per lavorare, ma quando l'eseguo ottengo il seguente;

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

giocare intorno alla console rivela quanto segue;

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 

Così ora sono curioso di sapere perché 2 oggetti vuoti ActiveRecord non sono uguali (dopo tutto, Array.new == Array.new restituisce vero), e che cosa devo fare per rendere il mio pass di prova.

risposta

6

Probabilmente si dovrebbe cambiare la vostra prova per qualcosa di simile:

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 

E si avrà lo stesso effetto. Se due oggetti non vengono salvati, non hanno le chiavi primarie per Rails, userà l'uguaglianza object_id per confrontarli, ecco perché non sono ==.

+2

Se l'autore vuole verificare se un record è sia nuovo e non ha attributi impostati, avrà bisogno anche uno controllo per 'should_not be_changed '. – jdoe

+0

Ottimo! Non lo sapevo. –

+1

Grazie per quello. Questo è logico. – brad

1

L'uguaglianza di attivatore è in gran parte relativa al fatto che i due oggetti corrispondano alla stessa riga del database (ad esempio due istanze corrispondenti alla stessa riga sono uguali, anche se inizi a cambiare gli attributi di uno di essi).

Se si chiama User.new due volte e si salva ciascun oggetto si finirebbe con 2 righe distinte nel database. Per me quindi ha senso che non dovrebbero essere uguali.

In termini di test è possibile fare 2 cose. Uno è verificare che l'utente assegnato sia un utente e che non sia salvato.

Un altro modo è qualcosa sulla falsariga di

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

oops: ben individuato! –

Problemi correlati