我可以在RSpec中存根STDERR吗?

fea*_*ool 3 ruby rspec stub

我有一个简单的函数,我想测试(也许主要是为了安抚simplecov).功能是:

module Utils
  extend self

  def blather(msg)
    msg = "=== " + msg
    STDERR.puts(msg)
    Rails.logger.debug(msg)
  end

end
Run Code Online (Sandbox Code Playgroud)

存根的RSpec文档说:

消息可以存储在任何类上,包括Ruby核心库中的消息.

但是以下内容:

# file: spec/lib/utils_spec.rb
require 'spec_helper'
describe Utils do
  context "blather" do
    it "should print to STDERR" do
      STDERR.any_instance.should_receive(:puts).with("=== zoo")    
      Utils.blather("zoo")
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

......我收到了一个错误

undefined method `any_instance' for #<IO:<STDERR>>
Run Code Online (Sandbox Code Playgroud)

暂不考虑这个测试是否有意义,是否可以存根STDERR(IO类)?这是失败的,因为它是一种类方法吗?或者这种测试有更合理的策略吗?

yfe*_*lum 6

首先,您通常应该使用$stderr而不是STDERR.

module Utils
  extend self

  def blather(msg)
    msg = "=== " + msg
    $stderr.puts(msg)
    Rails.logger.debug(msg)
  end

end
Run Code Online (Sandbox Code Playgroud)

要回答您的问题,您可以在RSpec中执行以下操作:

describe Utils do
  context "blather" do
    it "should print to stderr" do
      $stderr.should_receive(:puts).with("=== zoo")
      Utils.blather("zoo")
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

你只需将方法存根$stderr.should_receive.因为它$stderr是一个普通的对象,你可以像平常一样在它上面存储方法,并设置它的期望.