【问题标题】:Rake does not swallow RSpec message outputRake 不会吞下 RSpec 消息输出
【发布时间】:2017-08-02 21:42:45
【问题描述】:

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

rake resque:scheduler
rake environment resque:work

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

规格

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

耙任务

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

【问题讨论】:

    标签: ruby-on-rails ruby rspec rake


    【解决方案1】:

    您可以使用以下测试助手方法

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

    -- Temporarily disabling warnings in Ruby | Virtuous Code

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

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

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

    此外,您可以使用around hooksilent_warnings 包裹在RSpec 描述块中的所有测试周围;例如

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

    再次,谨慎使用它

    【讨论】:

    • 太棒了!我现在正在尝试这个。您是否建议将其放入 rspec 共享助手中?
    • 可能是您的rails_helper.rb 测试脚本,如果它仍然很小的话。否则,作为spec/support 目录中的新脚本(如果有的话),因为它将通过rails_helper.rb 脚本的行Dir[Rails.root.join("spec/support/**/*.rb")].each { |file| require file } 包含(如果存在)。或者甚至只是在使用它的几个测试范围内,因为我在其他地方不需要。
    • 效果很好,谢谢。是的 100% 谨慎。我只提倡在适用的情况下测试 rake 规范时使用它。您是否有任何关于stackoverflow.com/questions/42753946/… 的反馈意见?
    猜你喜欢
    • 2012-09-14
    • 2019-03-08
    • 2014-10-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 2015-10-23
    • 2018-07-05
    • 1970-01-01
    相关资源
    最近更新 更多