Search code examples
rubyerror-handlingrspecstderrargv

Ruby: RSpec fails when try to test STDERR output


I have collector.rb file with something like this:

class Collector
  def initialize(input)
    raise ArgumentError, 'must be positive integer' unless input.to_i.positive?
  end
  # more code...
end

begin
  Collector.new(*ARGV).do_something
rescue ArgumentError => e
  warn e.message
end

So when I do $ ruby collector.rb in terminal, I get wrong number of arguments (given 0, expected 1) as expected from Ruby docs

In my test file I have:

require 'rspec'
require './collector'

RSpec.describe Collector do
  let(:exec) { File.expand_path('../collector.rb', File.dirname(__FILE__)) }

  describe 'input in console' do
    context 'when wrong number of arguments' do
      specify { expect {`ruby #{exec} `}.to output('wrong number of arguments (given 0, expected 1)').to_stderr }
    end
  end
end

At the moment my test is failing as it cannot detect any output to STDERR although I'm following recommendation from here What am I doing wrong here, please? I'd be happy for any hint how to fix my code.


Solution

  • Backquotes in ruby run a command in a separate process. When you test to_output...to_stderr you test it on the parent process (RSpec), not the child process (ruby).

    In order to test child process stderr, you can use Open3.popen3 that gives you access to process stderr.

    Try sth like this (not tested):

    require 'open3'
    
    specify do
      Open3.popen3("ruby #{exec}") do |_stdin, _stdout, stderr|
        expect(stderr.read.strip).to eq('wrong number of arguments (given 0, expected 1)')
      end
    end