在Minitest中禁用rake任务的控制台输出

时间:2018-10-29 15:21:39

标签: ruby-on-rails rake minitest

我有一个rake任务,可以为控制台提供一些输出。此输出对于跟踪执行进度很有用,并且可以通过puts实现,如下所示:

task :clean => :environment do
  # Some code
  puts 'Doing work'
end

我已经用Minitest编写了该任务的测试,它提供了与手动调用相同的控制台输出。当我为项目运行整个测试套件时,这会弄乱“绿​​点”屏幕。

在测试环境中,是否可以选择禁用控制台输出(puts语句的效果)?可选地,当任务手动运行时,还有另一种显示消息的方式可以隐藏在测试环境中。

我已经探索了将puts替换为Rails.logger.info的选项。可以根据环境进行配置,但是它将输出显示到日志中,而不是在运行任务的终端窗口中显示。

1 个答案:

答案 0 :(得分:0)

您可以暂时将STDOUT重定向到/dev/null,然后再将其恢复。

original_stdout = $stdout
$stdout = File.open(File::NULL, 'w')

# ... do your tests ...

$stdout = original_stdout

另一种方法是将当前直接在Rake任务中的代码放入具有某种描述的对象中,并使用具有默认值的依赖项注入。例如:

# your rake file
task :clean => :environment do
  MyTaskObject.new.call
end

# my_task_object.rb
class MyTaskObject
  attr_reader :io

  def initialize(io = $stdout)
    @io = io
  end

  def call
    # ...actions
    io.puts "output"
    # more actions...
  end
end

然后,您可以直接测试而不是直接在测试中运行rake任务,然后传递您自己的I / O对象以代替stdout:

test '...' do
  io = StringIO.new

  MyTaskObject.new(io).call

  # assert here as usual
end

这种方法的一个优点是使用StringIO可以询问io.string,因此,如果需要,您还可以测试输出的内容。