unittest -在包中文件的初始化方法之前设置环境变量



我在我的项目中有以下布局:

MyProject
├── config
│   └── config.go
│   └── config_test.go
│   └── testdata
│         └── config.yaml
├── main.go
├── go.mod
├── go.sum  

配置。Go文件负责加载应用的配置,它应该在第一次导入配置包时自动发生。因此,我在那里配置了一个init方法,它将加载所有相关设置并进行设置:

package config
import ( "os" )
var (
Propery_x string
Property_y string
Property_z string
)
func init() {
LoadSettings()
}

func LoadSettings(){
Property_x = os.Getenv("X")
Property_y = os.Getenv("Y")
Property_z = os.Getenv("Z")

.....

我在配置的init方法之前的单元测试中设置这些环境值有问题。Go文件被调用。我遵循了我在这里找到的一些指导方针,建议做以下事情:

package config
import (
"os"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/assert"
)
func TestMain(m *testing.M) {
os.Setenv("X", "500")
m.Run()
os.Exit(0)
}

func TestLoadSettings(t *testing.T) {
assert.Equal(t, "500", Property_x, "values arent equal..")
}

您可以理解,代码仍然使用默认值,并且在config.go的init()之前没有设置env变量。

我考虑的另一个选项是:延迟加载。这样,我就不需要init方法,并且设置将在第一次有人试图访问配置时加载。

不要使用init函数

在启动main函数时调用config.LoadSettings。在测试中,您还可以定义事情的确切顺序。


还有一些包可以使用与flags包完全相同的语法加载配置文件、环境变量或命令行参数。例如namsral/标记

就像@TehSphinX建议的那样,我决定使用一个专门的方法来返回配置,而不是自动加载它。换句话说,我实现了延迟加载:

package settings
var (
settings       *Settings
configLoaded *AtomicBoolean = &AtomicBoolean{sync.Mutex{}, false}
)

type AtomicBoolean struct {
mu  sync.Mutex
val bool
}

type Settings struct {
property_x string
property_y string
property_z string
}

func (ab *AtomicBoolean) getValue() bool {
var val bool = false
ab.mu.Lock()
val = ab.val
ab.mu.Unlock()
return val
}
func (ab *AtomicBoolean) setValue(val bool) {
ab.mu.Lock()
ab.val = val
ab.mu.Unlock()
}

func GetSettings() *Settings {
if !settingsgLoaded.getValue(){
loadSettings()
}

}
func loadSettings(){
Property_x = os.Getenv("X")
Property_y = os.Getenv("Y")
Property_z = os.Getenv("Z")
...
settingsLoaded.setValue(true)
.....

现在在我的测试中,我可以设置环境变量,只有在调用GetSettings函数之后:

package settings
func TestLoadSettings(t testing.T){
os.Setenv("X',"500")
assert.Equal(GetSettings().property_x,"500")
}

最新更新