2011-01-03 8 views
6

Mam trudności z uzyskaniem testu rspec na przekazanie kontrolera. Chciałbym przetestować działanie akcji POST. Używam szyn (3.0.3), kankana (1.4.1), opracowania (1.1.5), rspec (2.3.0)Nie można przetestować za pomocą kontrolera rspec POST utwórz akcję (programuj i klikaj)

Model jest martwy prosty

class Account < ActiveRecord::Base 
    attr_accessible :name 
end 

Kontroler jest standardem jak również (w kierunku prostopadłym do rusztowań)

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 

i rspec Test Chciałbym PASS (usprawiedliwia tytuł może nie najwłaściwszy)

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 

Mimo wszystko mogę to

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 

Inne działania mogą być testowane i przechodzą (tj Poznawanie)

tutaj jest test dla Poznawanie

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 

i zakończenia Tutaj jest plik zdolność

class Ability 
    include CanCan::Ability 

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

Jakieś pomysły? Domyślam się, że używam złych oczekiwań rspec, ponieważ kod działa (po prostu test nie działa zgodnie z oczekiwaniami!)

Odpowiedz

23

response.should be_success zwraca wartość true, jeśli kod odpowiedzi znajduje się w zakresie 200-299. Ale operacja tworzenia przekierowań, więc kod odpowiedzi zostaje ustawiony na 302, a więc niepowodzenie.

Możesz to sprawdzić, używając response.should redirect_to. Sprawdź wyjście standardowego generatora kontroler RSpec dla przykładu, który może wyglądać następująco:

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 Twoja odpowiedź była doskonała. Musiałem napisać kilka tyków, żeby to osiągnąć, ale najważniejsze było to, że powinno to być przekierowanie. – Dimitris

+0

Myślę, że ta odpowiedź powinna być zaakceptowaną odpowiedzią. –

+0

Głosowałem za tą zaakceptowaną odpowiedzią, ponieważ większość ludzi uważa tę odpowiedź za najbardziej użyteczną – Dimitris

3

rspec test, który dostał test, aby przejść było (dzięki radą zetetic'S):

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