问题描述
我正在尝试为ActiveRecord编写测试-Rails使用MiniTest进行测试,因此我没有选择测试框架的方法.我要测试的条件是这样的(从db:create rake任务开始,出于本示例的目的,将其拉入方法中):
I'm trying to write a test for ActiveRecord - and Rails uses MiniTest for its tests, so I don't have a choice of test framework. The condition I want to test is this (from the db:create rake tasks, pulled into a method for the purpose of this example):
def create_db
if File.exist?(config['database'])
$stderr.puts "#{config['database']} already exists"
end
end
因此,我想测试$ stderr是否在文件存在的情况下收到看跌期权,否则不这样做.在RSpec中,我会这样做:
So, I want to test that $stderr receives puts if the File exists, but otherwise does not. In RSpec, I would have done this:
File.stub :exist? => true
$stderr.should_receive(:puts).with("my-db already exists")
create_db
MiniTest中的等效项是什么? assert_send的行为似乎不符合我的预期(并且实际上没有任何文档-应该在执行之前发布,例如should_receive还是之后?).我当时想我可以在测试期间暂时将$ stderr设置为一个模拟,但是$ stderr仅接受响应写入的对象.您不能在模拟中对方法进行存根,并且我不想在stderr模拟中设置对write方法的期望-这意味着我正在测试要模拟的对象.
What's the equivalent in MiniTest? assert_send doesn't seem to behave as I expect (and there's not really any documentation out there - should it go before the execution, like should_receive, or after?). I was thinking I could temporarily set $stderr with a mock for the duration of the test, but $stderr only accepts objects that respond to write. You can't stub methods on mocks, and I don't want to set an expectation of the write method on my stderr mock - that'd mean I'm testing an object I'm mocking.
我觉得我在这里没有正确使用MiniTest,因此请多多指教.
I feel like I'm not using MiniTest the right way here, so some guidance would be appreciated.
一个更新:这是一个可行的解决方案,但它是设置对:write的期望,这不对.
An update: here is a solution that works, but it is setting the expectation for :write, which is Not Right.
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
推荐答案
因此,事实证明Rails将Mocha与Minitest结合使用,这意味着我们可以利用Mocha更好的消息期望.有效的测试如下所示:
So, it turns out Rails uses Mocha in combination with Minitest, which means we can take advantage of Mocha's far nicer message expectations. A working test looks like this:
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
这篇关于MiniTest中的方法期望的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!