2011-05-16 135 views
8

我对使用rspec生成的脚手架控制器规格发生了些什么感到困惑。这似乎是有道理的,直到我给我的应用程序添加授权,现在我需要更新我的测试。这是怎么回事:rspec stub(:new).with ...?

MyClass.stub(:new).with('these' => 'params') { mock_my_class(:save => true) } 

在我控制我创造了新的记录(它需要CURRENT_USER ID是有效的),当合并散列成PARAMS。 MyClass.new(PARAMS [:my_class] .merge(:USER_ID => current_user.id))

测试失败

expected: ({"these"=>"params"}) 
got: ({"these"=>"params", "user_id"=>315}) 

这是有道理的,因为新的方法接收测试失败PARAMS它没”没想到。它预计会收到{'these'=>'params'}但它实际上收到{'these'=>'params','user_id'=> 1234}

所以我的自然反应是调整测试,因为新方法应该收到{'these'=>'params','user_id'=> 1234}并返回模拟对象。

所以我添加到测试如下:

MyClass.stub(:new).with({'these' => 'params', 'user_id' => @user.id}) { mock_my_class(:save => true) } 

这里就是我打通一个循环抛出。测试的输出如下:

expected: ({"these"=>"params", "user_id"=>298}) 
got: ({"these"=>"params"}) 

看起来好像是一个成功的测试魔法般地回避我。我确信这些结果是有逻辑的原因的,但我似乎无法弄清楚。

任何帮助? :)

注:

RSpec的网站说以下内容:

Account.should_receive(:find).with("37").and_return(account) 

Account.stub!(:find).and_return(account) 

这是很容易跟着它只是似乎很奇怪的产生支架不会包含这些方法(除非我拙劣的东西是可能的(:)


通行证

login_admin 
describe "with valid params" do 
    it "assigns a newly created forum_sub_topic as @forum_sub_topic" do 
    ForumSubTopic.stub(:new) { mock_forum_sub_topic(:save => true) } 
    ForumSubTopic.should_receive(:new).with({"these"=>"params", "user_id"=> @admin.id}) #PASS! 
    post :create, :forum_sub_topic => {'these' => 'params'} 
    assigns(:forum_sub_topic).should be(mock_forum_sub_topic) #PASS! 
    end 
end 

失败

login_admin 
describe "with valid params" do 
    it "assigns a newly created forum_sub_topic as @forum_sub_topic" do 
    ForumSubTopic.stub(:new).with({'these' => 'params', 'user_id' => @user.id}) { mock_forum_sub_topic(:save => true) } 
    post :create, :forum_sub_topic => {'these' => 'params'} 
    assigns(:forum_sub_topic).should be(mock_forum_sub_topic) 
    end 
end 
+0

很高兴看到您的rspec代码的完整代码,而不仅仅是新的stub代码。我经常发现我忘记了所有的模型行为(因为我们只是测试控制器的行为是否正确,假设模型假定工作正常)。 – jaydel 2011-05-16 12:29:48

+0

我增加了更多细节。这是唯一失败的例子。 – 2011-05-16 14:47:15

回答

4

“永远不要相信一个瘾君子”,正如俗话所说。人们也可以说,“永远不要相信脚手架”。

好的,这有点太苛刻了。脚手架尽力找出哪些参数适用于您生成的模型/控制器,但它不知道嵌套资源(这是我假设您使用的),所以它不会生成user_id参数散列。补充一点:

post :create, :forum_sub_topic => {:user_id=>@user.id} 

these_params关键是作为一个例子产生的 - 将其删除,并添加任何参数都需要控制器创建MyClass

关于with选项:

MyClass.stub(:new) {mock_model(MyClass,:save=>true)} 

然后MyClass的将任何new消息与模拟响应:stubshould_receive如果你这样做只会存根指出,符合规定条件的,即消息。如果,另一方面,你这样做:

MyClass.stub(:new).with({:bogus=>37}) {mock_model(MyClass,:save=>true)} 

然后MyClass的将只有new时也接收{:bogus=>37}作为参数做出回应。

+0

这非常有帮助。谢谢。有一件事是,user_id没有通过生产中的参数传递,所以测试不能准确地模拟行为。我不确定这是否重要。 – 2011-05-18 17:37:24