RSpec: ожидание, что модель не работает во время тестирования контроллера

Я пытаюсь написать функциональный тест. Мой тест выглядит следующим образом:

describe PostsController do
  it "should create a Post" do
    Post.should_receive(:new).once
    post :create, { :post => { :caption => "ThePost", :category => "MyCategory" } }
  end
end

Мой PostsController (часть его на самом деле) выглядит следующим образом:

PostController < ActiveRecord::Base

  def create
    @post = Post.new(params[:post])
  end

end

При выполнении теста я всегда получаю ошибку, которая говорит о том, что класс Post ожидал: новый, но так и не получил его. Тем не менее, фактический пост создан.

Я новичок в RSpec. Я что-то пропустил?

2 ответа

РЕДАКТИРОВАТЬ - выбросить предыдущий мусор

Это должно делать то, что вы хотите

require File.dirname(__FILE__) + '/../spec_helper'

describe PostsController do
  it "should create a Post" do
    attributes = {"Category" => "MyCategory", "caption" => "ThePost"}
    Post.stub!(:new).and_return(@post = mock_model(Post, :save => false))
    Post.should_receive(:new).with( attributes ).and_return @post
    post :create, { :post => attributes }
  end
end

Предполагается, что вы используете собственную библиотеку rspecs и что у вас установлен гем rspec_rails.

Вы можете использовать controller метод Rspec-rails для проверки ожидаемых сообщений на контроллерах, как описано здесь. Так что один из способов проверить ваш create действие таково:

describe PostsController do
  it "should create a Post" do
    controller.should_receive(:create).once
    post :create, { :post => { :caption => "ThePost", :category => "MyCategory" } }
  end
end

РЕДАКТИРОВАТЬ (выдвигая аргумент)

Возможно, вы захотите подумать, стоит ли писать тест, который зависит от реализации create действие. Если вы тестируете что-либо кроме должных обязанностей контроллера, вы рискуете нарушить тесты при рефакторинге, и вам придется вернуться и переписать тесты при изменении реализации.

Задача действия create - создать что-то, поэтому проверьте это:

Post.count.should == 1

и тогда вы узнаете, было ли сообщение создано, независимо от того, как оно было создано.

РЕДАКТИРОВАТЬ № 2 (гм...)

По исходному вопросу я вижу, что вы уже знаете, что сообщение создается. Я по-прежнему утверждаю, что вы должны проверять поведение, а не реализацию, и что проверка того, получает ли модель сообщение, не очень хорошая вещь в тесте контроллера. Может быть, вы отлаживаете, а не тестируете?

Другие вопросы по тегам