2

Ruby では、ブロックを受け取るメソッドが次のようになるのはかなり一般的です。

class File
  def open(path, mode)
    perform_some_setup
    yield
  ensure
    do_some_teardown
  end
end

メソッドが次のように見えるのもかなり慣用的です。

def frobnicate
  File.open('/path/to/something', 'r') do |f|
    f.grep(/foo/).first
  end
end

ファイルシステムにヒットしない仕様を書きたいと思います。これにより、ファイルから正しい単語を引き出すことが保証されます。たとえば、次のようになります。

describe 'frobnicate' do
  it 'returns the first line containing the substring foo' do
    File.expects(:open).yields(StringIO.new(<<EOF))
      not this line
      foo bar baz
      not this line either
    EOF
    expect(frobnicate).to match(/foo bar baz/)  
  end
end

ここでの問題は、 への呼び出しをモック化することで、File.openその戻り値も削除してしまったことです。つまり、frobnicateが を返すことになりnilます。ただし、チェーンに次のようなものを追加するFile.returns('foo bar baz')と、関心のあるコードのいずれにも実際にはヒットしないテストになってしまいます。のブロックの内容はfrobnicate何でも実行でき、テストは引き続きパスします。

frobnicateファイルシステムにアクセスせずにメソッドを適切にテストするにはどうすればよいですか? 私は特定のテスト フレームワークに特に執着しているわけではないので、もしあなたの答えが「それをやってくれるこのすばらしい宝石を使ってください」なら、私はそれでOKです。

4

2 に答える 2