【发布时间】:2017-08-08 18:49:54
【问题描述】:
我正在用 Go 语言构建一个简单的 CLI 工具,它充当各种密码存储(Chef Vault、Ansible Vault、Hashicorp Vault 等)的包装器。这部分是作为熟悉 Go 的练习。
在处理这个问题时,我遇到了一种情况,我正在编写测试并发现我需要为很多事情创建interfaces,只是为了能够模拟依赖项。因此,为了测试,一个相当简单的实现似乎有一堆抽象。
但是,我最近在阅读 The Go Programming Language 并找到了一个示例,他们通过以下方式模拟了它们的依赖项。
func Parse() map[string]string {
s := openStore()
// Do something with s to parse into a map…
return s.contents
}
var storeFunc = func openStore() *Store {
// concrete implementation for opening store
}
// and in the testing file…
func TestParse(t *testing.T) {
openStore := func() {
// set contents of mock…
}
parse()
// etc...
}
所以为了测试,我们将这个具体实现存储在一个变量中,然后我们基本上可以在测试中重新声明该变量并让它返回我们需要的内容。
否则,我会为此创建一个interface(尽管目前只有一个实现)并将其注入Parse 方法。这样,我们可以模拟它进行测试。
所以我的问题是:每种方法的优缺点是什么?什么时候更适合为模拟目的创建接口,而不是将具体函数存储在变量中以便在测试中重新声明?
【问题讨论】:
标签: go