2011-01-03 10 views
6

Ho difficoltà a ottenere un test rspec per il passaggio di un controller. Vorrei testare che il POST crea azione. Sto usando rotaie (3.0.3), Cancan (1.4.1), ideare (1.1.5), RSpec (2.3.0)Impossibile testare con il controller rspec Azione POST create (concepisce e cancan)

Il modello è morto semplice

class Account < ActiveRecord::Base 
    attr_accessible :name 
end 

Il controller è di serie nonché (direttamente da ponteggi)

class AccountsController < ApplicationController 
    before_filter :authenticate_user!, :except => [:show, :index] 
    load_and_authorize_resource 
    ... 

    def create 
    @account = Account.new(params[:account]) 

    respond_to do |format| 
     if @account.save 
     format.html { redirect_to(@account, :notice => 'Account was successfully created.') } 
     format.xml { render :xml => @account, :status => :created, :location => @account } 
     else 
     format.html { render :action => "new" } 
     format.xml { render :xml => @account.errors, :status => :unprocessable_entity } 
     end 
    end 
    end 

e il test RSpec vorrei passare è (scusate il titolo, forse non il più appropriato uno)

it "should call create on account when POST create is called" do 
    @user = Factory.create(:user) 
    @user.admin = true 
    @user.save 

    sign_in @user #this is an admin 
    post :create, :account => {"name" => "Jimmy Johnes"} 
    response.should be_success 
    sign_out @user 

end 

Eppure tutto quello che ottiene è

AccountsController get index should call create on account when POST create is called 
Failure/Error: response.should be_success 
expected success? to return true, got false 
# ./spec/controllers/accounts_controller_spec.rb:46 

altre azioni possono essere testati e non passano (vale a dire Ottenere nuovi)

qui è il test per ottenere nuovi

it "should allow logged in admin to call new on account controller" do 
    @user = Factory.create(:user) 
    @user.admin=true 
    @user.save 

    sign_in @user #this is an admin 
    get :new 
    response.should be_success 
    sign_out @user 
end 

e per il completamento qui è il file capacità

class Ability 
    include CanCan::Ability 

    def initialize(user) 
    user ||= User.new 
    if user.admin? 
     can :manage, :all 
    else 
     can :read, :all 
    end 
    end 
end 

Tutte le idee? La mia ipotesi è che sto usando l'aspettativa rspec sbagliata, dal momento che il codice funziona (è solo che il test non funziona come desiderato!)

risposta

23

response.should be_success restituisce true se il codice di risposta è nell'intervallo 200-299. Ma l'azione crea reindirizza, quindi il codice di risposta viene impostato su 302, quindi l'errore.

È possibile verificare questo utilizzando response.should redirect_to. Controllare l'uscita del generatore controller standard RSpec per un esempio, che potrebbe assomigliare a questo:

it "redirects to the created account" do 
    Account.stub(:new) { mock_account(:save => true) } 
    post :create, :account => {} 
    response.should redirect_to(account_url(mock_account)) 
    end 
+0

Zetetic , la tua risposta è stata eccellente. Ho dovuto fare qualche tweek per farlo passare, ma il succo era che avrebbe dovuto essere un reindirizzamento. – Dimitris

+0

Penso che questa risposta dovrebbe essere la risposta accettata. –

+0

Ho votato come risposta accettata poiché la maggior parte delle persone sembra trovare questa risposta la più utile – Dimitris

3

Il test RSpec che ha ottenuto la prova da superare è stato (grazie ai consigli di Zetetic):

it "should call create on account when POST create is called" do 
    @user = Factory.create(:user) 
    @user.admin = true 
    @user.save 

    sign_in @user #this is an admin 
    account = mock_model(Account, :attributes= => true, :save => true) 
    Account.stub(:new) { account } 

    post :create, :account => {} 
    response.should redirect_to(account_path(account)) 
    sign_out @user 

end 
Problemi correlati