Init功能中断单元测试

时间:2017-04-14 10:41:27

标签: unit-testing go

在我想测试的包中,我有一个init函数,它加载包含我想用来运行我的应用程序的一些东西的配置文件。但是,我不希望在运行单元测试时触发此init函数。

在单元测试中是否有任何方法可以跳过或阻止调用此init函数?

一些片段来说明问题:

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
}

测试用例:

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

1 个答案:

答案 0 :(得分:4)

我不确定是否有更好的方法可以做到这一点,但是如果你考虑在运行init func之前初始化包级变量的事实你可以用一个标志告诉你是否你“是否正在运行测试。

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)
    }
}

// ...

在您的测试文件中,您可以执行以下操作:

// 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)
    }
}

您可以在此处详细了解初始化顺序:https://golang.org/ref/spec#Program_initialization_and_execution