unit-testinggozerolog

How do I test that zerolog logger raised log event of type error?


In my Go app I moved error logging into a separate function

package logging

import "github.com/rs/zerolog"

func LogError(logger zerolog.Logger, err error) {
    logger.Error().Err(err).Msg("")
}

and want to create a small test to ensure the error log event was been raised. For reproduction purposes I won't show the test file but code from the playground https://go.dev/play/p/Jnyz51JemTh

package main

import (
    "errors"
    "fmt"

    "github.com/rs/zerolog"
)

func main() {
    logger := zerolog.Nop()
    testError := errors.New("test error")
    logHook := &logHook{}

    logger.Hook(logHook)

    LogError(logger, testError)

    amountOfLogEvents := len(logHook.logEvents)

    fmt.Printf("Expected amount of log events: 1\nActual amount of log events: %v", amountOfLogEvents)

    // TODO inspect logHook.logEvents[0]
}

func LogError(logger zerolog.Logger, err error) {
    logger.Error().Err(err).Msg("")
}

type logHook struct {
    logEvents []zerolog.Event
}

func (logHook *logHook) Run(logEvent *zerolog.Event, level zerolog.Level, message string) {
    logHook.logEvents = append(logHook.logEvents, *logEvent)
}

You should see the output

Expected amount of log events: 1

Actual amount of log events: 0

I thought I could create a custom hook to catch the event and inspect it. Unfortunately I'm struggling with two things

Do you know what's wrong and how to fix it?


Solution

    1. Nop cant apply the hooks,And the Logger is not a pointer
    // Nop returns a disabled logger for which all operation are no-op.
    func Nop() Logger {
        return New(nil).Level(Disabled)
    }
    // Hook returns a logger with the h Hook.
    func (l Logger) Hook(h Hook) Logger {
        l.hooks = append(l.hooks, h)
        return l
    }
    
    1. For the same reason, Your logHook should be
    func (logHook *logHook) Run(logEvent *zerolog.Event, level zerolog.Level, message string) {
        logHook.logEvents = append(logHook.logEvents, *logEvent)
    }
    

    So we get this and can pass the test, see playground

    logger := zerolog.New(os.Stdout)
    logHook := &logHook{}
    logger = logger.Hook(logHook)