2016-02-22 3 views
3

Есть ли способ получить доступ к списку предупреждений Ruby внутри примера RSpec? Я получаю следующую ошибку в библиотеке, которую я тестирую, и хочу написать для нее единичный тест.Как я могу проверить в RSpec, имеет ли код, который я загрузил, какие-либо предупреждения Ruby?

warning: previous definition of BUILD_FILE was here 

ответ

2

Я закончил тем, что инициировал новый процесс и оценил выход процесса. В моем случае проблема была переопределенной константой, поэтому я тестирую, дважды загружая класс в новый процесс Ruby, а затем используя поток IO для чтения вывода:

it 'should not redefine BUILD_FILE constant' do 
    root_path = "#{File.dirname(__FILE__)}/../../../../" 
    cmd = "load \"#{root_path}libraries/build_file.rb\";" 
    ruby_path = 'C:/opscode/chefdk/embedded/bin/ruby.exe' 

    pipe_cmd_in, pipe_cmd_out = IO.pipe 
    pid = Process.spawn("#{ruby_path} -e '#{cmd} #{cmd}'", :out => pipe_cmd_out, :err => pipe_cmd_out) 
    Process.wait(pid) 
    pipe_cmd_out.close 
    output = pipe_cmd_in.read 
    puts "OUTPUT = #{output}" 

    expect(output).to_not match(/previous\sdefinition\sof\sBUILD_FILE/) 
end 
1

Рубиновые предупреждения пойти $stderr, так что вы можете обернуть его с объектом, который шпионит предупреждения, написанные на ней:

В спецификации/поддержки/warning_spying_stderr.rb:

require 'delegate' 

class WarningSpyingIO < SimpleDelegator 
    attr_reader :strings 

    def initialize(delegate) 
    @strings = [] 
    super 
    end 

    def write(string) 
    if string.include? 'warning: ' # in case anything other than a Ruby warning goes to $stderr 
     @strings << string 
    end 
    __getobj__.write string 
    end 

end 

$stderr = WarningSpyingIO.new $stderr 

В спецификация/warning_spec.rb:

describe "My code" do 
    it "has no warnings" do 
    FOO = 'foo' 
    FOO = 'bar' 
    expect($stderr.strings).to be_empty 
    end 
end 

спецификация терпит неудачу с

expected `[ 
    "spec/warning_spec.rb:4: warning: already initialized constant FOO\n", 
    "spec/warning_spec.rb:3: warning: previous definition of FOO was here\n" 
].empty?` to return true, got false 

Я поставил линию, которая генерирует предупреждение теста в спецификации для удобства, но он должен работать одинаково хорошо для любого предупреждения, выданного после $stderr угнали.

я не встретил необходимость прекратить слежку, прежде чем RSpec вышел, но если вы делаете вы можете сделать

$stderr = $stderr.__getobj__ 

в точке, в которой вы хотите, чтобы остановить слежку.

Смежные вопросы