问题
I have an application and I want to test if I get correct messages from my logger.
A short example (you may switch between log4r and logger):
gem 'minitest'
require 'minitest/autorun'
require 'log4r'
#~ require 'logger'
class Testlog < MiniTest::Test
def setup
if defined? Log4r
@log = Log4r::Logger.new('log')
@log.outputters << Log4r::StdoutOutputter.new('stdout', :level => Log4r::INFO)
else
@log = Logger.new(STDOUT)
@log.level = Logger::INFO
end
end
def test_silent
assert_silent{ @log.debug("hello world") }
assert_output(nil,nil){ @log.debug("Hello World") }
end
def test_output
#~ refute_silent{ @log.INFO("Hello") }#-> NoMethodError: undefined method `refute_silent'
assert_output("INFO log: Hello World\n",''){ @log.info("Hello World") }
end
end
But I get:
1) Failure:
Testlog#test_output [minitest_log4r.rb:27]:
In stdout.
Expected: "INFO log: Hello World\n"
Actual: ""
On my output screen I see the message.
I have similar results with Log4r::StderrOutputter
and Log4r::Outputter.stdout
.
So it seems it is send to the output screen, but it is not catched by minitest in STDOUT or STDERR.
Before I start to write a minitest-log4r-Gem:
Is there a possibility to test logger-output in minitest?
If not: Any recommendations how to implement a minitest-log4r-Gem?
Examples what I could imagine:
- define new outputter for minitest (Log4r::MinitestOutputter)
- Mock the logger.
- new assertions (add the new outputter as parameter?):
assert_message('INFO log: Hello World'){ @log.info("Hello World") }
assert_messages(:info => 1, :debug => 2){ @log.info("Hello World") }
to count messages.assert_info_messages('Hello World'){ @log.info("Hello World") }
assert_debug_messages('Hello World'){ @log.info("Hello World") }
回答1:
In meantime I created a minitest-logger-Gem
A code example how to use it:
require 'log4r'
require 'minitest-logger'
class Test_log4r < MiniTest::Test
def setup
@log = Log4r::Logger.new('log')
@log.level = Log4r::INFO
end
def test_output_1
assert_log(" INFO log: Hello World\n"){ @log.info("Hello World") }
end
def test_output_regex
assert_log(/Hello World/){ @log.info("Hello World") }
end
def test_silent
assert_silent_log(){
@log.debug("Hello World")
#~ @log.info("Hello World") #uncomment this to see a failure
}
refute_silent_log(){
@log.warn("Hello World") #comment this to see a failure
}
end
end
During the test a temporary outputter is added to the logger @log
. After the test the outputter is removed again.
The gem supports log4r and logger.
回答2:
You can set up a pipe, pass the writer from the pipe to the logger, and then use the reader from the pipe to test your assertions.
http://ruby-doc.org/core-2.1.0/IO.html#method-c-pipe
Something like:
require 'logger'
r, w = IO.pipe
log = Logger.new(w)
log.info "testing info log message"
output = r.gets
puts "Test passed: #{!!(/testing/ =~ output)}"
来源:https://stackoverflow.com/questions/29392292/how-can-i-test-logger-messages-with-minitest