Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Init function breaking unit tests

In the package I want to test, I have an init function that loads the configuration file containing some stuff I want to use to run my application. However, I don't want to trigger this init function while running my unit tests.

Is there any way for skipping or preventing this init function to be called during the unit tests?

Some snippets to illustrate the question:

func init() {
    var err error // Necessary to prevent config variable shadowing
    config, err = loadConfig("./client/config.yml")
    if err != nil {
        log.Fatal(err)
    }
}

func loadConfig(filepath string) (*Config, error) {
    viper.SetConfigFile(filepath)
    if err := viper.ReadInConfig(); err != nil {
        return nil, fmt.Errorf("Error loading config file: %s", err)
    }
  (...)
}

// New returns a Config value(!)
func New() Config {
    return *config
}

A test case:

func TestNew(t *testing.T) {
    expected := &Config{}
    observed := New()
    if !reflect.DeepEqual(observed, expected) {
        t.Errorf("observed %+v. expecting %+v\n", observed, expected)
    }
}
like image 525
Alessandro Resta Avatar asked Apr 14 '17 10:04

Alessandro Resta


1 Answers

I'm not sure whether there's a nicer way of doing this, but if you consider the fact that package-level variables are initialized before the init func is run you can use a flag to tell you whether you're running tests or not.

var _testing = false

func init() {
    if _testing {
        return
    }

    var err error // Necessary to prevent config variable shadowing
    config, err = loadConfig("./client/config.yml")
    if err != nil {
        log.Fatal(err)
    }
}

// ...

And in your test file you could do something like this:

// not nice but works
var _ = (func() interface{} {
    _testing = true
    return nil
}())

func TestNew(t *testing.T) {
    expected := &Config{}
    observed := New()
    if !reflect.DeepEqual(observed, expected) {
        t.Errorf("observed %+v. expecting %+v\n", observed, expected)
    }
}

You can read more on the initialization order here: https://golang.org/ref/spec#Program_initialization_and_execution

like image 71
mkopriva Avatar answered Oct 30 '22 13:10

mkopriva