ActiveRecord のテストを作成しようとしています - Rails はそのテストに MiniTest を使用するため、テスト フレームワークを選択できません。テストしたい条件は次のとおりです (db:create rake タスクから、この例の目的でメソッドにプルされます):
def create_db
if File.exist?(config['database'])
$stderr.puts "#{config['database']} already exists"
end
end
そのため、File が存在する場合は $stderr が put を受け取り、それ以外の場合は受け取らないことをテストしたいと思います。RSpec では、次のようにします。
File.stub :exist? => true
$stderr.should_receive(:puts).with("my-db already exists")
create_db
MiniTest で同等のものは何ですか? assert_send は、期待どおりに動作していないようです (実際にはドキュメントはありません。should_receive のように、実行前に実行する必要がありますか?)。テスト中に一時的に $stderr をモックで設定できると思っていましたが、$stderr は書き込みに応答するオブジェクトしか受け入れません。モックでメソッドをスタブすることはできません。また、stderr モックで write メソッドの期待値を設定したくありません。つまり、モックしているオブジェクトをテストしていることになります。
ここで MiniTest を正しく使用していないように感じるので、いくつかのガイダンスをいただければ幸いです。
更新: これは機能するソリューションですが、 :write に対する期待を設定しています。これは正しくありません。
def test_db_create_when_file_exists
error_io = MiniTest::Mock.new
error_io.expect(:write, true)
error_io.expect(:puts, nil, ["#{@database} already exists"])
File.stubs(:exist?).returns(true)
original_error_io, $stderr = $stderr, error_io
ActiveRecord::Tasks::DatabaseTasks.create @configuration
ensure
$stderr = original_error_io unless original_error_io.nil?
end