新泽西州最大新手的RSpec2错误:( | factory_girl,authlogic,rails3

时间:2010-09-09 18:08:41

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

我正在编写一个失败的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

2 个答案:

答案 0 :(得分: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),并且正在发生,因为您正在使用Factories在测试数据库中创建用户。您可以取出存根,测试仍然有效,但是以击中数据库为代价。

另一个提示:如果你想弄清楚为什么控制器测试不起作用,有时知道它是否被before过滤器阻止是有帮助的。您可以通过以下方式检查:

controller.should_receive(:update)

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

答案 1 :(得分:2)

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)

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

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