我正在尝试为 ActiveRecord 编写一个测试 - Rails 使用 MiniTest 进行测试,所以我没有选择测试框架。我想测试的条件是这样的(来自 db:create rake 任务,出于本示例的目的,被拉入方法中):
def create_db
if File.exist?(config['database'])
$stderr.puts "#{config['database']} already exists"
end
end
因此,我想测试 $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,所以一些指导将不胜感激。
更新:这是一个可行的解决方案,但它is设置 :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