Невозможно протестировать с помощью POST-контроллера rspec действие создания (разработка и канкан)

У меня возникли трудности с прохождением теста rspec для контроллера. Я хотел бы проверить, работает ли действие POST create. Я использую рельсы (3.0.3), канкан (1.4.1), разработку (1.1.5), rspec (2.3.0)

Модель до безобразия проста

class Account < ActiveRecord::Base
  attr_accessible :name 
end

Контроллер тоже стандартный (прямо из строительных лесов)

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

и тест rspec, который я хотел бы пройти (извините за название, возможно, не самый подходящий)

 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

Но все, что я получаю, это

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

Другие действия могут быть проверены и действительно проходят (т.е. ПОЛУЧИТЬ новое)

вот тест для GET new

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

и для доработки вот файл способностей

class Ability
  include CanCan::Ability

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

Любые идеи? Я предполагаю, что я использую неправильное ожидание rspec, поскольку код работает (просто тест не работает должным образом!)


person Dimitris    schedule 03.01.2011    source источник


Ответы (2)


response.should be_success возвращает true, если код ответа находится в диапазоне 200–299. Но действие create перенаправляет, поэтому код ответа устанавливается равным 302, что приводит к сбою.

Вы можете проверить это, используя response.should redirect_to. Для примера проверьте вывод стандартного генератора контроллера RSpec, который может выглядеть так:

  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
person zetetic    schedule 03.01.2011
comment
zetetic, ваш ответ был превосходным. Мне пришлось сделать несколько настроек, чтобы заставить его пройти, но суть была в том, что это должно было быть перенаправление. - person Dimitris; 04.01.2011
comment
Я проголосовал за это как за принятый ответ, так как большинство людей считают этот ответ наиболее полезным. - person Dimitris; 21.08.2013

Тест rspec, который прошел тест, был (благодаря совету 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
person Dimitris    schedule 04.01.2011