Ruby 特性测试rake任务将输出添加到stdout。如何避免这种情况?

Ruby 特性测试rake任务将输出添加到stdout。如何避免这种情况?,ruby,rspec,rake,stdout,Ruby,Rspec,Rake,Stdout,我尝试对Rake任务进行特性测试并捕获其输出: 这是一个完整的集成测试(特性测试),它 意味着我想对它进行端到端的测试。所以我对存根不感兴趣 我们开发了一些ConsoleRenderer类,只是测试一下当我运行任务时,我 请参见stdout中的某些输出 实现过程大大简化 namespace :output do task :world do print 'hello world' end task :mars do print 'hello mars' end

我尝试对Rake任务进行特性测试并捕获其输出:

这是一个完整的集成测试(特性测试),它 意味着我想对它进行端到端的测试。所以我对存根不感兴趣 我们开发了一些ConsoleRenderer类,只是测试一下当我运行任务时,我 请参见
stdout
中的某些输出

实现过程大大简化

namespace :output do
  task :world do
    print 'hello world'
  end

  task :mars do
    print 'hello mars'
  end
end
以及特性测试(rspec 3.3):

运行此操作时,会以某种方式将过去运行的输出相加:

$ bundle exec rspec spec/features/output_spec.rb --order defined
.FF

Failures:

  1) some output outputs again
     Failure/Error: expect { Rake::Task['output:world'].invoke }.to output('hello world').to_stdout
       expected block to output "hello world" to stdout, but output "hello worldhello world"
     # ./spec/features/output_spec.rb:18:in `block (2 levels) in <top (required)>'

  2) some output outputs mars
     Failure/Error: expect { Rake::Task['output:mars'].invoke }.to output('hello mars').to_stdout
       expected block to output "hello mars" to stdout, but output "hello marshello marshello mars"
     # ./spec/features/output_spec.rb:22:in `block (2 levels) in <top (required)>'
这一切都很顺利

注意,在运行

Rake::Task['output:mars'].invoke
Rake::Task['output:mars'].reenable
Rake::Task['output:mars'].invoke
输出“hello mars”一次,然后再次输出“hello mars”。问题并不是这样 在这样的环境中自我复制

我需要重置、重新启用、重新导入、截断或其他什么
更改,使输出不累加?

结果表明,
可重新启用
不是正确的调用方式。相反,我应该使用。通过其自身的文档,“通常用于单元测试”


注意:这解决了问题,但我仍然不知道问题中描述的设置在某个点上运行任务三次的确切原因和方式。因此,与我自己的答案相比,我更喜欢一个解释行为为何如此以及为什么运行
clear
没有这样的答案。

之所以执行两次或三次,是因为您在每个块之前加载了任务:

before do
  Rails.application.load_tasks
end
改为在:all之前使用

并且可以选择在加载之前使用
Rails.application.clear
,因为如果您在另一个规范中加载了任务,它们仍然会在那里

Rake::Task['output:mars'].invoke
Rake::Task['output:mars'].reenable
Rake::Task['output:mars'].invoke
after do
  Rake.application.clear
end
before do
  Rails.application.load_tasks
end