RSpec のタグを付けていますが、特に RSpec に限らないと思ったので、このタイトルにしました。
想定するケース
- 標準入力に
x
が渡される場合をテストしたい - 標準出力に出力される文字列を検査したい
こんなとき、StringIO が活躍してくれます。
このクラスは文字列に IO クラスと同じインタフェースを提供してくれます。
つまり、gets
で読み込んだり、puts
で書き込んだりできます。
テストコード例
標準入力
## 標準入力を文字列 x のオブジェクトにすり替える
$stdin = StringIO.new(x)
do_some_tests() # 標準入力を受け取って何かをするテスト
expect(...).to ... # 結果の検査
$stdin = STDIN # 元に戻す
標準出力
# 標準出力を StringIO オブジェクトにすり替える
$stdout = StringIO.new
do_something() # 標準出力に書き込む処理
output = $stdout.string # 出力結果の取得
expect(output).to eq ... # 値の検査
$stdout = STDOUT # 元に戻す
結びに
Web で検索すると、特に入力の方では、標準入力をスタブ化する例をいくつか見かけましたが、このやり方であればわざわざスタブ化しなくても良さそうです。(というか、スタブ化と同等と言ってもいいのかもしれません。)