3

我正在尝试为 ActiveRecord 编写测试——Rails 使用 MiniTest 进行测试,所以我没有选择测试框架。我要测试的条件是这样的(来自 db:create rake 任务,为了本示例的目的,拉入了一个方法):

def create_db
  if File.exist?(config['database'])
    $stderr.puts "#{config['database']} already exists"
  end
end

因此,我想测试 $stderr 如果文件存在则接收放置,否则不接收。在 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
4

1 回答 1

0

因此,Rails 将 Mocha 与 Minitest 结合使用,这意味着我们可以利用 Mocha 更好的消息期望。工作测试如下所示:

def test_db_create_when_file_exists
  File.stubs(:exist?).returns(true)

  $stderr.expects(:puts).with("#{@database} already exists")

  ActiveRecord::Tasks::DatabaseTasks.create @configuration
end
于 2012-06-16T23:27:06.933 回答