LoggerHandlerKit.HandlerWrapper (Logger Handler Kit v0.1.0)
View SourceLogger Handler which wraps another handler to make it more testable.
Logger handlers can be annoying to test for a number of reasons:
- If they encounter an error, they are detached instead of crashing, which makes it harder to understand what's going on, as the test failure will not report the actual error.
- Once OTP gets involved, logger handlers might find themselves executing in exotic parts of the system. This makes it difficult for tests to know when to proceed with assertions.
HandlerWrapper
expects the following configuration keys:
test_pid
– PID of a test process.ref
– a reference to accompany messages it will send to the test process.handler_module
– a handler module to wrap.inside_config
– a config to pass to the wrapped handler.
Whenever the log/2
callback is invoked, the wrapper handler will pass the
log event to the wrapped module, catch any error if needed, and once finished,
send a {ref, :log_call_completed}
or {ref, {:handler_error, {kind, reason, __STACKTRACE__}}}
message to the test process.
HandlerWrapper
is a fairly low level part of the toolbox, so before using
it, check out LoggerHandlerKit.Arrange.add_handler/4
and
LoggerHandlerKit.Assert.assert_logged/1
.
Example
iex(2)> ref = make_ref()
#Reference<0.3804490001.995622913.186390>
iex(3)> :logger.add_handler(:wrapped_handler, LoggerHandlerKit.HandlerWrapper, %{
...(3)> config: %{test_pid: self(), ref: ref, handler_module: :logger_std_h, inside_config: %{}},
...(3)> formatter: Logger.default_formatter()
...(3)> })
:ok
iex(4)> Logger.info("Hello!")
18:27:38.096 [info] Hello!
18:27:38.096 [info] Hello!
:ok
iex(5)> receive do msg -> msg end
{#Reference<0.3804490001.995622913.186390>, :log_call_completed}