开发者

Test for warnings using RSpec

开发者 https://www.devze.com 2023-02-19 21:05 出处:网络
Is开发者_高级运维 it somehow possible to test warnings i Ruby using RSpec? Like this: class MyClass

Is开发者_高级运维 it somehow possible to test warnings i Ruby using RSpec?

Like this:

class MyClass
  def initialize
    warn "Something is wrong"
  end
end

it "should warn" do
  MyClass.new.should warn("Something is wrong")
end


warn is defined in Kernel, which is included in every object. If you weren't raising the warning during initialization, you could specify a warning like this:

obj = SomeClass.new
obj.should_receive(:warn).with("Some Message")
obj.method_that_warns

Spec'ing a warning raised in the initialize method is quite more complex. If it must be done, you can swap in a fake IO object for $stderr and inspect it. Just be sure to restore it after the example

class MyClass
  def initialize
    warn "Something is wrong"
  end
end

describe MyClass do
  before do
    @orig_stderr = $stderr
    $stderr = StringIO.new
  end

  it "warns on initialization" do
    MyClass.new
    $stderr.rewind
    $stderr.string.chomp.should eq("Something is wrong")
  end

  after do
    $stderr = @orig_stderr
  end
end


There is a good article with custom expectation which solves exactly your problem: http://greyblake.com/blog/2012/12/14/custom-expectations-with-rspec/

So it would like:

expect { MyClass.new }.to write("Something is wrong").to(:error)

Base on that article you can create you own expectation to use it like this:

expect { MyClass.new }.to warn("Something is wrong")


If warning raises during initialization you can use output expectation:

expect do
  described_class.new
end.to output('test message').to_stderr


This is my solution, I define a custom matcher has_warn

require 'rspec'
require 'stringio'

module CustomMatchers
  class HasWarn
    def initialize(expected)
      @expected = expected
    end

    def matches?(given_proc)
      original_stderr = $stderr
      $stderr = StringIO.new
      given_proc.call
      @buffer = $stderr.string.strip
      @expected.include? @buffer.strip
    ensure
      $stderr = original_stderr
    end

    def supports_block_expectations?
      true
    end

    def failure_message_generator(to)
      %Q[expected #{to} get message:\n#{@expected.inspect}\nbut got:\n#{@buffer.inspect}]
    end

    def failure_message
      failure_message_generator 'to'
    end

    def failure_message_when_negated
      failure_message_generator 'not to'
    end

  end

  def has_warn(msg)
    HasWarn.new(msg)
  end
end

now you can use this function as follow after include the CustomMatchers:

expect{ MyClass.new }.to has_warn("warning messages")
0

精彩评论

暂无评论...
验证码 换一张
取 消