0

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

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 类期望 :new 但从未得到它。不过,实际的帖子已创建。

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

4

2 回答 2

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。

于 2010-04-30T15:16:57.490 回答
0

您可以使用controllerRspec-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(嗯...)

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

于 2010-04-29T18:21:25.073 回答