Search code examples
unit-testinggologging

How to manage initialisation code of dependencies for tests


I have a log wrapper (uses logrus implementation underneath) and I’m using this package to log across my app. The way I do this is by passing the logger variable to each of the required packages through dependency injection.

Here, when writing test cases for each of the packages, I have to write some code to initialise the logger package. How do we avoid having to write initialisation code for the test cases of every package which uses the logger?

logger/log.go

type Logger interface {
    Info(args ...interface{})
    Infof(format string, keyvals ...any)
    InfoWithFields(fields map[string]interface{}, msg ...interface{})

    Debug(args ...interface{})
    Debugf(format string, keyvals ...any)
    DebugWithFields(fields map[string]interface{}, msg ...interface{})
}

app_test.go

func setupLogrusLogger() (*bytes.Buffer, Logger) {
    buf := &bytes.Buffer{}
    logrusLogger := log.New()
    logrusLogger.Out = buf
    logrusLogger.Formatter = &log.JSONFormatter{}
    return buf, NewLogrusLogger(logrusLogger)
}

func TestSomething(t *testing.T) {
  // buf can be used to inspect what gets logged if required
  buf, logger := setupLogrusLogger()
  Something(logger)
}

Here, for each of the packages which uses logger, I'd have to initialise the logger by defining something similar to setupLogrusLogger. Is there any way to avoid having to write this separately for each package I'm writing tests for?


Solution

  • Export the dependency initializing function and declare it in a non-_test.go file so that the other packages can import and reuse it. If you'd like to separate the test logic from the package's normal code you can move the initializing function to a package that provides utilities for testing.

    And, as long as you import such test-utility packages only from within _test.go files (and not from normal files), the test utility code won't make it into the actual program's compiled binary.


    Examples of such test-utility packages can be found in the standard library:

    net/http/httptest

    Package httptest provides utilities for HTTP testing.

    net/internal/socktest

    Package socktest provides utilities for socket testing.

    os/exec/internal/fdtest

    Package fdtest provides test helpers for working with file descriptors across exec.

    testing/quick

    Package quick implements utility functions to help with black box testing.

    testing/fstest

    Package fstest implements support for testing implementations and users of file systems.

    testing/iotest

    Package iotest implements Readers and Writers useful mainly for testing.