0

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

enter image description here

halfer
  • 19,824
  • 17
  • 99
  • 186
Chris Hough
  • 3,389
  • 3
  • 41
  • 80

1 Answers1

0

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

sonna
  • 600
  • 4
  • 10
  • Awesome! I am trying this now. Do you recommend putting this in an rspec shared helper? – Chris Hough Mar 13 '17 at 02:21
  • 1
    Probably your `rails_helper.rb` test script if it is still quite small. Otherwise, as a new script within your `spec/support` directory (if you have one), since it will be included via the `rails_helper.rb` script's line `Dir[Rails.root.join("spec/support/**/*.rb")].each { |file| require file }`, if it exists. Or even just within the scope of couple tests where it is used, because my not be needed elsewhere. – sonna Mar 13 '17 at 02:24
  • That worked perfectly, thank you. Yes 100% on sparingly. I would only advocate using this while testing rake specs where applicable. By any chance would you have feedback on http://stackoverflow.com/questions/42753946/ruby-rails-rspec-rake-resque-task-spies ? – Chris Hough Mar 13 '17 at 02:26