Rake 不吞下 RSpec 消息输出 [英] Rake does not swallow RSpec message output

查看:64
本文介绍了Rake 不吞下 RSpec 消息输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的规范提供了我所希望的覆盖范围,但是,rspec 输出中显示了以下 2 条消息:

rake resque:scheduler耙环境要求:工作

我如何在规范运行期间吞下这些,以免它们搞砸我的 nyancat 格式化程序?

规格

describe 'database rake task' doinclude_context '耙'let(:task_paths) { ['tasks/heroku'] }在做之前invoke_task.reenable结尾# rubocop: 禁用所有描述 'myapp:heroku' 做上下文 ':setup' 做上下文 ':secrets' 做let(:task_name) { 'myapp:heroku:setup:secrets' }上下文 'with env' 做它有效"做expect(File).to receive(:exist?).with('.env').and_return(true)expect_any_instance_of(Object).to receive(:system).with('heroku config:push --remote production').and_return(true)期望 { invoke_task.invoke }.to 输出("\n更新生产机密\n").to_stdout结尾结尾上下文没有环境"做它有效"做expect(File).to receive(:exist?).with('.env').and_return(false)期望 { invoke_task.invoke }.to raise_error("\n你缺少 .env 文件\n").and(output("\n更新生产机密\n").to_stdout)结尾结尾结尾结尾结尾描述schedule_and_work"做让(:task_name){'schedule_and_work'}上下文 'with process fork' 做它有效"做期望(进程).接收(:叉).and_return(真)expect_any_instance_of(Object).to receive(:system).with('rake environment resque:work', {}).and_return(true)期望(invoke_task.invoke).成为结尾结尾上下文没有进程叉"做它有效"做期望(进程).接收(:叉).and_return(假)期望(处理).接收(:等待).and_return(真)expect_any_instance_of(Object).to receive(:system).with('rake resque:scheduler', {}).and_return(true)期望(invoke_task.invoke).成为结尾结尾结尾# rubocop: 启用所有结尾

耙任务

namespace :myapp do命名空间:heroku do命名空间:设置做desc '修改秘密'任务:秘密做puts "\n更新生产机密\n"提出\n你缺少 .env 文件\n"除非 File.exist?('.env')system('heroku config:push --remote production')结尾结尾结尾结尾# 在 2 个免费 dynos 上运行 resque 调度程序# https://grosser.it/2012/04/14/resque-scheduler-on-heroku-without-extra-workers/任务:schedule_and_work 做如果 Process.forksh '耙环境resque:工作'别的sh 'rake resque:scheduler'进程等待结尾结尾

解决方案

可以使用下面的测试辅助方法

<块引用>

需要'stringio'defsilent_warningsold_stderr = $stderr$stderr = StringIO.new屈服确保$stderr = old_stderr结尾

-- 在 Ruby 中暂时禁用警告 |良性代码

并用 silent_warnings 方法包装 Rake 任务的调用;像这样

silent_warnings 做期望 { invoke_task.invoke }.to 输出("\n更新生产机密\n").to_stdout结尾

但是,请谨慎使用它,因为它会吞下块代码中产生的所有警告(打印到 $stdout),从而使将来更难调试.

此外,您可以使用 around 钩子;例如

around(:example) 做 |example|无声警告{example.run}结尾

再次,谨慎使用

My spec provides coverage like I had hoped, however, the following 2 messages are displaying in the rspec output:

rake resque:scheduler
rake environment resque:work

How do I swallow these during spec runs so they do not screw up my nyancat formatter?

Spec

describe 'database rake task' do
  include_context 'rake'
  let(:task_paths) { ['tasks/heroku'] }

  before do
    invoke_task.reenable
  end

  # rubocop:disable all
  describe 'myapp:heroku' do
    context ':setup' do
      context ':secrets' do
        let(:task_name) { 'myapp:heroku:setup:secrets' }

        context 'with env' do
          it 'works' do
            expect(File).to receive(:exist?).with('.env').and_return(true)
            expect_any_instance_of(Object).to receive(:system).with('heroku config:push --remote production').and_return(true)
            expect { invoke_task.invoke }.to output(
              "\nUpdating Secrets for production\n"
            ).to_stdout
          end
        end

        context 'without env' do
          it 'works' do
            expect(File).to receive(:exist?).with('.env').and_return(false)
            expect { invoke_task.invoke }.to raise_error("\nYou are missing the .env file\n").and(output(
              "\nUpdating Secrets for production\n"
            ).to_stdout)
          end
        end
      end
    end
  end

  describe 'schedule_and_work' do
    let(:task_name) { 'schedule_and_work' }

    context 'with process fork' do
      it 'works' do
        expect(Process).to receive(:fork).and_return(true)
        expect_any_instance_of(Object).to receive(:system).with('rake environment resque:work', {}).and_return(true)
        expect(invoke_task.invoke).to be
      end
    end

    context 'without process fork' do
      it 'works' do
        expect(Process).to receive(:fork).and_return(false)
        expect(Process).to receive(:wait).and_return(true)
        expect_any_instance_of(Object).to receive(:system).with('rake resque:scheduler', {}).and_return(true)
        expect(invoke_task.invoke).to be
      end
    end
  end
  # rubocop:enable all
end

Rake Task

namespace :myapp do
  namespace :heroku do
    namespace :setup do
      desc 'modify secrets'
      task :secrets do
        puts "\nUpdating Secrets for production\n"
        raise "\nYou are missing the .env file\n" unless File.exist?('.env')
        system('heroku config:push --remote production')
      end
    end
  end
end

# Run resque scheduler on 2 free dynos
# https://grosser.it/2012/04/14/resque-scheduler-on-heroku-without-extra-workers/
task :schedule_and_work do
  if Process.fork
    sh 'rake environment resque:work'
  else
    sh 'rake resque:scheduler'
    Process.wait
  end
end

解决方案

You can use the following test helper method

require 'stringio'

def silent_warnings
  old_stderr = $stderr
  $stderr = StringIO.new
  yield
ensure
  $stderr = old_stderr
end

-- Temporarily disabling warnings in Ruby | Virtuous Code

And wrap the invoking of a Rake task with silent_warnings method; like so

silent_warnings do
  expect { invoke_task.invoke }.to output(
    "\nUpdating Secrets for production\n"
  ).to_stdout
end

However, use it sparingly, since it swallow all warnings (printed to $stdout) produced within the block code, making it harder to debug in the future.

Also, you can wrap silent_warnings around all tests within an RSpec describe block using then around hook; e.g.

around(:example) do |example|
  silent_warnings { example.run }
end

Again, use it sparingly

这篇关于Rake 不吞下 RSpec 消息输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆