如何使用RSpec在已经存根的控制器方法上存根方法?

时间:2012-02-25 15:53:16

标签: ruby-on-rails rspec mocking

当我试图取消关注的用户不存在时,我会抛出一个设置Flash错误消息的异常,并将用户重定向回他们所在的页面。

所有对twitter gem的访问都是由TwitterManager类处理的,这是一个常规的ruby类,它扩展了ActiveModel :: Naming以启用mock_model。

现在我很难弄清楚应该如何测试它。下面的代码有效,但感觉非常错误。我可以存根twitter.unfollow方法的唯一方法是使用controller.send(:twitter).stub(:unfollow).and_raise(Twitter :: Error :: NotFound.new("",{} ))

我尝试使用TwitterManager.any_instance.stub(:unfollow),但这显然不符合我的想法。

我怎样才能做得更好?我完全误解了什么?

规格

describe TwitterController do

  before(:each) do
    controller.stub(:twitter).and_return(mock_model("TwitterManager", unfollow: true, follow: true))
  end

  it "unfollows a user when given a nickname" do
    @request.env['HTTP_REFERER'] = '/followers'
    post 'unfollow', id: "existing_user"
    response.should redirect_to followers_path
  end

  describe "POST 'unfollow'" do
    it "does not unfollow a user that does not exist" do
      controller.send(:twitter).stub(:unfollow).and_raise(Twitter::Error::NotFound.new("", {}))
      @request.env['HTTP_REFERER'] = '/followers'
      post 'unfollow', id: "non_existing_user"

      flash[:error].should_not be_nil
      flash[:error].should have_content("not found, could not unfollow")
      response.should redirect_to followers_path
    end
  end

控制器

def unfollow
    begin
      twitter.unfollow(params[:id])
      respond_to do |format|
        format.html { redirect_to :back, notice: "Stopped following #{params[:id]}" }
      end
    rescue Twitter::Error::NotFound
      redirect_to :back, :flash => { error: "User #{params[:id]} not found, could not unfollow user" }
    end
  end

[更多代码]

 private
  def twitter
    twitter_service ||= TwitterFollower.new(current_user)
  end

Rspec 2.8.0 Rails 3.2.0

1 个答案:

答案 0 :(得分:1)

您可以通过将模拟TwitterManager保存为before块中的实例变量并直接在该对象上进行存根来清理它:

describe TwitterController do

  before(:each) do
    @twitter = mock_model("TwitterManager", unfollow: true, follow: true)
    controller.stub(:twitter).and_return(@twitter)
  end

  # ...

  describe "POST 'unfollow'" do
    it "does not unfollow a user that does not exist" do
      @twitter.stub(:unfollow).and_raise(Twitter::Error::NotFound.new("", {}))
      # ...
    end
  end
end

但我不会说你在做什么是“非常错误”: - )