如何在Rspec中模拟方法调用

时间:2013-09-08 00:09:34

标签: ruby rspec

我是TDD和Rspec的新手。我试图找出如何确保在测试中调用方法:

module Authentication
  include WebRequest

  def refresh_auth_token(refresh_token)
    "refreshing token"
  end
end


class YouTube
  include Authentication
  attr_accessor :uid, :token, :refresh

  def initialize(uid, token, refresh)
    @uid = uid
    @token = token
    @refresh = refresh

    # if token has expired, get new token
    if @token == nil and @refresh
      @token = refresh_auth_token @refresh
    end
  end

end

这是我的测试:

$f = YAML.load_file("fixtures.yaml")

describe YouTube do
  data = $f["YouTube"]
  subject { YouTube.new(data["uid"], data["token"], data["refresh"]) }
  its(:token) { should == data["token"] }

  context "when token is nil" do
    subject(:without_token) { YouTube.new(data["uid"], nil, data["refresh"]) }
    its(:token) { should_not be_nil }
    it { YouTube.should_receive(:refresh_auth_token).with(data["refresh"]) }
  end

end

但它失败了:

  

)当令牌为零时的YouTube        失败/错误:{YouTube.should_receive(:refresh_auth_token).with(data [“refresh”])}          ().refresh_auth_token( “1 / HBTNQ93otm1cSQH8kKauij3jO0kZQYfgH5J-hBtAP8k”)              预期:1次参数:(“1 / HBTNQ93otm1cSQH8kKauij3jO0kZQYfgH5J-hBtAP8k”)              收到:带参数的0次:(“1 / HBTNQ93otm1cSQH8kKauij3jO0kZQYfgH5J-hBtAP8k”)        #./lib/youtube/you_tube_test.rb:14:in块中的“块(3级)”

我在此测试中尝试做的是确定@token为零,并且提供了@refresh,如果在{{1}上调用了refresh_auth_token }}。这种模拟和存根的事情有点令人困惑。

1 个答案:

答案 0 :(得分:3)

首先,您要使用any_instance

YouTube.any_instance.should_receive(:refresh_auth_token).with(data["refresh"])

目前,您正在检查是否正在调用类方法refresh_auth_token。它不是,因为它不存在。

接下来,当代码在构造函数中执行时,该行不会捕获调用,因为该对象已在规范之前的主题行中创建。

这是最简单的解决方案:

  context "when token is nil" do
    it "refreshed the authentation token" do
        YouTube.any_instance.should_receive(:refresh_auth_token).with(data["refresh"]) 
        YouTube.new(data["uid"], nil, data["refresh"]) 
    end
  end