3

テストしたい単純な関数があります(おそらく、ほとんどの場合、simplecovをなだめるためです)。機能は次のとおりです。

module Utils
  extend self

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

end

スタブの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

... エラーが発生する

undefined method `any_instance' for #<IO:<STDERR>>

このテストに意味があるかどうかという質問はさておき、STDERR (IO クラス) をスタブ化することは可能ですか? クラスメソッドだから失敗?それとも、この種のテストのためのより賢明な戦略はありますか?

4

3 に答える 3

6

まず、通常は$stderrではなく を使用する必要がありますSTDERR

module Utils
  extend self

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

end

あなたの質問に答えるために、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

を介してメソッドをスタブするだけ$stderr.should_receiveです。は通常のオブジェクトであるため$stderr、通常のようにメソッドをスタブ化したり、期待値を設定したりできます。

于 2012-04-11T15:26:16.607 に答える
1

当たり前。STDIO はクラスではありません。これは IO のインスタンスであるため、次のように変更します。

STDERR.any_instance.should_receive(:puts).with("=== zoo")

STDERR.should_receive(:puts).with("=== zoo")

テストに合格します。

于 2012-04-11T16:08:46.867 に答える