【问题标题】:An RSpec2 error by the biggest newb in New Jersey :( | factory_girl, authlogic, rails3新泽西州最大的新手的 RSpec2 错误 :( | factory_girl, authlogic, rails3
【发布时间】:2010-09-09 18:08:40
【问题描述】:

我正在编写一个失败的 rspec 场景:

 (#<User:0x1056904f0>).update_attributes(#<RSpec::Mocks::ArgumentMatchers::AnyArgMatcher:0x105623648>)
     expected: 1 time
     received: 0 times

users_controller_spec.rb:

describe "Authenticated examples" do
  before(:each) do
    activate_authlogic
    @user = Factory.create(:valid_user)
    UserSession.create(@user)
  end

describe "PUT update" do
    it "updates the requested user" do
      User.stub!(:current_user).and_return(@user)
      @user.should_receive(:update_attributes).with(anything()).and_return(true)
      put :update, :id => @user , :current_user => {'email' => 'Trippy'}
      puts "Spec Object Id : " + "#{@user.object_id}"
 end

users_controller.rb:

def update
  @user = current_user
  puts "Controller Object ID is : " + "#{@user.object_id}"

  respond_to do |format|
    if @user.update_attributes(params[:user])
      format.html { redirect_to(root_url, :notice => 'Successfully updated profile.') }
      format.xml  { head :ok }
    else
      format.html { render :action => "edit" }
      format.xml  { render :xml => @user.errors, :status => :unprocessable_entity }
    end
  end
end

user.rb - 工厂

Factory.define :valid_user, :class => User do |u|
  u.username "Trippy"
  u.password "password"
  u.password_confirmation "password"
  u.email "elephant@gmail.com"
  u.single_access_token "k3cFzLIQnZ4MHRmJvJzg"
  u.id "37"
end

【问题讨论】:

  • 将我的 rspec 场景更新为所有答案的建议,但仍然返回相同的错误。
  • 更新了对current_user进行stub的特殊性,并更新了上面的错误。

标签: ruby-on-rails testing ruby-on-rails-3 rspec rspec2


【解决方案1】:

Authlogic 的标准辅助方法(如current_user)不会直接调用User.find。我相信它确实是current_user_session.user,其中current_user_session 调用UserSession.find,所以你没有直接调用User.find。你可以在那里做一些花哨的链存根,但我的建议只是将它添加到你的控制器规范中,而不是你当前的存根:

stub!(:current_user).and_return(@user)

在 RSpec2 中你可能需要这样做

controller.stub!(:current_user).and_return(@user)

编辑:这应该是您的整个规范文件:

describe "Authenticated examples" do
  before(:each) do
    activate_authlogic
    @user = Factory.create(:valid_user)
    UserSession.create(@user)
  end

describe "PUT update" do

  describe "with valid params" do
    it "updates the requested user" do
      stub!(:current_user).and_return(@user)
      @user.should_receive(:update_attributes).with(anything()).and_return(true)
      put :update, :id => @user , :current_user => {'email' => 'Trippy'}
    end
 end

【讨论】:

  • 好的。我承认。但是为什么 update_attributes 没有通过呢?
  • 您在规范中创建的 @user 实例变量上设置了对 update_attributes 的期望,但如果您的 User.find 存根没有返回该 exact 实例变量,它确实返回的用户没有对其设置期望。尝试在控制器和规范中添加puts @user.object_id,看看它们是否不同。
  • 不确定如何同时获取这些 puts 语句。对于控制器,我添加了 puts @user.obect_id,但我会将它放在规范中的哪个位置?或者我应该怎么说?它不会从我运行规范返回 puts 语句。
  • it ... do 块内的任意位置添加 puts 应该会在您运行规范时显示输出,无论是通过 rake 还是通过 specrspec
  • 规范对象 ID:2192867960 && 控制器对象 ID 为:2192167180 !!!哦,def现在接近了:D
【解决方案2】:

我认为您将存根与消息期望混淆了。线

User.should_receive(:find)

告诉 Rspec 期望 User 模型收到一条查找消息。鉴于:

User.stub!(:find)

替换 find 方法以便测试可以通过。在您的示例中,您要测试的是 update_attributes 是否被成功调用,因此这应该是消息期望所在的位置,所有其他测试代码的工作只是设置先决条件。

尝试将该行替换为:

User.stub!(:find).and_return(@user)

请注意,find 返回的是对象,而不仅仅是它的 id。另外,请注意,在这里删除 find 只是为了加快速度。正如所写的示例成功通过should_receive(:find),并且 正在发生,因为您正在使用工厂在测试数据库中创建用户。您可以取出存根,测试应该仍然有效,但代价是访问数据库。

另一个提示:如果您想找出控制器测试不工作的原因,有时了解它是否被before 过滤器阻止会很有帮助。您可以通过以下方式检查:

controller.should_receive(:update)

如果失败,则无法到达 update 操作,可能是因为 before 过滤器已重定向请求。

【讨论】:

  • 存根清除了查找错误。很有意义。更新错误确实失败了,所以我为每个子声明( GET 、 PUT、 POST、 DELETE )移动了经过身份验证的示例 before() 方法。但它仍然在第二个错误时失败,` (#<0x10564d3a8>
  • &gt;&gt;&gt;&gt;&gt;&gt;
猜你喜欢
  • 1970-01-01
  • 2011-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-16
  • 1970-01-01
  • 2016-06-16
  • 2013-08-02
相关资源
最近更新 更多