2011-01-03 2 views
6

J'ai du mal à obtenir un test rspec pour un contrôleur. Je voudrais tester que l'action créer un POST fonctionne. J'utilise des rails (3.0.3), cancan (1.4.1), mettre au point (1.1.5), rspec (2.3.0)Impossible de tester avec le contrôleur rspec Créer une action POST (concevoir et cancan)

Le modèle est simple comme bonjour

class Account < ActiveRecord::Base 
    attr_accessible :name 
end 

Le contrôleur standard ainsi (tout droit sorti d'un échafaudage)

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 

et le test rspec je voudrais passer est (excusez le titre, peut-être pas le plus approprié)

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 

Pourtant, tout ce que je reçois est

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 

D'autres actions peuvent être testées et ne passent (à savoir GET nouvelle)

ici est le test pour obtenir de nouveaux

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 

et pour l'achèvement est ici le fichier de 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 

Toutes les idées? Ma conjecture est que j'utilise la mauvaise espérance rspec, puisque le code fonctionne (c'est juste que le test ne fonctionne pas comme souhaité!)

Répondre

23

response.should be_success retourne vrai si le code de réponse est dans la gamme 200-299. Mais l'action create redirige, donc le code de réponse est mis à 302, donc l'échec.

Vous pouvez tester cela en utilisant response.should redirect_to. Vérifiez la sortie du générateur de contrôleur standard RSpec pour un exemple, ce qui pourrait ressembler à ceci:

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 , ta réponse était excellente. J'ai dû faire quelques tweeks pour le faire passer, mais l'essentiel était que cela aurait dû être une redirection. – Dimitris

+0

Je pense que cette réponse devrait être la réponse acceptée. –

+0

J'ai voté pour cette réponse car la plupart des gens semblent trouver cette réponse utile – Dimitris

3

Le test rspec qui a obtenu le test de passer a été (grâce aux conseils de Zététique):

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 
Questions connexes