Golang:使用init()函数进行测试

16

你好,我是Go的新手,正在编写一个简单的应用程序,该应用程序从环境变量中获取一些配置信息。如下所示,我在init函数中执行此操作。

type envVars struct {
    Host     string `env:"APP_HOST"`
    Username string `env:"APP_USERNAME"`
    Password string `env:"APP_PASSWORD"`
}

var envConfig envVars

func init() {
    if err := env.Parse(&envConfig); err != nil {
        log.Fatal(err)
    }
}

我编写了一个测试来验证环境变量是否被正确读取。但问题是,我的程序的初始化函数甚至在我的测试初始化函数之前就已经被调用了。有没有办法在我的程序初始化函数被调用之前进行一些设置。

func init() {
    os.Setenv("APP_HOST", "http://localhost:9999")
    os.Setenv("APP_USERNAME", "john")
    os.Setenv("APP_PASSWORD", "doe")
}

func TestEnvConfig(t *testing.T) {
    assert.NotNil(t, envConfig)
    assert.Equal(t, "http://localhost:9999", envConfig.Host)
}

2
不完全是。init函数的目的是在所有其他函数之前自动调用。如果你想在init之前做一些事情,你需要将它移到init外面。(读取环境变量也不是你通常测试的东西。读取它们的代码应该单独进行测试) - JimB
也许这会有所帮助 https://dev59.com/N2Ag5IYBdhLWcg3wU5m8 - asr9
4个回答

11
您可以使用TestMain函数来控制测试前和测试后发生的事情。
例如:
func TestMain(m *testing.M) {
    // Write code here to run before tests
    
    // Run tests
    exitVal := m.Run()
    
    // Write code here to run after tests

    // Exit with exit value from tests
    os.Exit(exitVal)
}

func TestYourFunc(t *testing.T) {
    // Test code
}

0
你可以在真正的测试之前添加一个名为 Test_parse_params(t *testing.T) 的函数。看起来像这样:
type envVars struct {
    Host     string `env:"APP_HOST"`
    Username string `env:"APP_USERNAME"`
    Password string `env:"APP_PASSWORD"`
}

var envConfig envVars

//parse command params
func Test_parse_params(t *testing.T) {
    if err := env.Parse(&envConfig); err != nil {
        log.Fatal(err)
    }
}

func Test_real_test(t *testing.T) {
....
}

0
不,你不应该期望init()按某种顺序运行(实际上它是基于文件加载顺序的,但仍然不应该依赖它)。
简单的方法是,如果你想测试它,使用一个shell脚本来运行你的测试,或者类似Makefile的东西。
Shell示例:
set +e
export APP_HOST=http://localhost:9999
export APP_USERNAME=john
export APP_PASSWORD=doe
go test .
unset APP_HOST
unset APP_USERNAME
unset APP_PASSWORD

或者一个单行命令:

APP_HOST=http://localhost:9999 APP_USERNAME=john APP_PASSWORD=doe go test .

编辑:

另一种解决方案:将读取环境从初始化函数中移出。

func init(){
  envInit()
}
func envInit(){
 if err := env.Parse(&envConfig); err != nil {
        log.Fatal(err)
    }
}

然后您可以在测试中再次调用 envInit 来确保其有效。

-1

虽然不是最理想的,但这对我来说可行。 在你正在测试的包内:

func init() {
    if len(os.Args) > 1 && os.Args[1][:5] == "-test" {
        log.Println("testing")//special test setup goes goes here
        return // ...or just skip the setup entirely
    }
    //...
}

这不是正确的做法。请参考 https://golang.org/pkg/testing/ 或 https://dev59.com/N2Ag5IYBdhLWcg3wU5m8。 - asr9

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接