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です。