RSpec:测试控制器时模型的预期不起作用

时间:2010-04-29 15:25:15

标签: ruby-on-rails testing rspec expectations

我正在尝试编写功能测试。我的测试如下:

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

My PostsController(实际上是其中的一部分)如下所示:

PostController < ActiveRecord::Base

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

end

运行测试我总是收到一个失败,它说Post类预期:new但从未得到它。仍然,创建了实际的帖子。

我是RSpec的新手。我错过了什么吗?

2 个答案:

答案 0 :(得分:1)

编辑 - 扔掉以前的垃圾

这应该做你想要的事情

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 gem。

答案 1 :(得分:0)

您可以使用Rspec-rails的controller方法测试控制器上的消息期望,如here所述。因此,测试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操作实现的测试是否是个好主意。如果您正在测试除控制器的正确职责之外的任何其他内容,那么您在重构时可能会破坏测试,并且在实现更改时必须返回并重写测试。

创建操作的工作是创建一些东西 - 所以测试一下:

Post.count.should == 1

然后您就知道是否创建了帖子,而不依赖于 的创建方式。

编辑#2 (嗯...)

我从你原来的问题中看到你已经知道正在创建帖子。我仍然认为你应该测试行为,而不是实现,并且检查模型是否收到消息在控制器测试中不是一件好事。也许你正在做的是调试,而不是测试?