mardi 16 juin 2020

Is it possible to test code in init (Arrange/Act/Assert)?

I know there is a duplicate of this but really it doesn't answer the question to my satisfaction: Golang: Testing with init() func

I have some code in a logger:


var env = os.Getenv("ENVIRONMENT")
var logLevel = os.Getenv("LOG_LEVEL")
var version = os.Getenv("VERSION")

func init() {
    if logLevel != "" {
        newLevel, err := logrus.ParseLevel(logLevel)
        if err != nil {
            panic(fmt.Sprintf("Failed to parse log level, got %v", logLevel))
        }
        logger.SetLevel(newLevel)
    } else {
        if env == "dev" || env == "stg" || env == "int" {
            logger.SetLevel(logrus.DebugLevel)
        }
    }
    customLogger = logger.WithFields(logrus.Fields{
        "env":             env,
        "service-id":      "foo",
        "service-version": version,
    })
}

I'd like to test that the level is debug when I set the env var to debug. I have a feeling this is not possible, since init functions will run after the import but before TestMain.

My best effort:

func TestMain(m *testing.M) {
    key := "LOGLEVEL"
    os.Setenv(key, "fatal")
    if os.Getenv(key) != "fatal" {
        panic("Log level not correctly set")
    }
    code := m.Run()
    os.Exit(code)
}

func TestLoggingLevels(t *testing.T) {
    t.Run("sets level when LOG_LEVEL is set in env", func(t *testing.T) {
        level := logger.GetLevel().String()
        fmt.Println("Level: ", level)
        fatalLevel := logrus.FatalLevel.String()
        assert.Assert(t, level == fatalLevel,
            "Logger was not set to Fatal level after init, got:", level)
    })
... 

The test fails, even though the assert in TestMain does not. This tells me two things:

  1. init runs after import but before TestMain
  2. Code in init is effectively untestable.

Is there some workaround here that I don't know about? Can I import in a test (seems absurd, but maybe)?

Aucun commentaire:

Enregistrer un commentaire