我有一个程序包,其中未导出结构并导出了New函数来创建它,并导出了在此结构上运行的函数(例如,此处建议使用Return an unexported type from a function)。 如果在同一位置运行该函数,则称为New,可以运行package函数,但是无法将此实体发送给另一个函数。 无需将我所有的代码都放在一个函数中的最佳方法是什么?
例如,此方法有效:
client := package.New()
client.Foo()
但这不起作用:
client := package.New()
hello(client)
func hello(client interface{}) {
client.Foo()
}
答案 0 :(得分:1)
您的hello
函数本质上需要的是具有Foo
函数的事物。这就是为什么go具有接口。返回未导出的类型没有错(事实上,这很普遍,通常也是正确的做法)。我要做的是这样:
package foobar
// whatever thing that has a Foo function
type FClient interface {
Foo()
}
func Hello(client FClient) {
client.Foo() // will work
}
之所以这么做,是因为能够对这段代码进行单元测试:
package foobar_test
import (
"testing"
)
type testFC struct {
callCount uint64
}
// implement interface
func (t testFC) Foo() {
testFC.callCount++
}
func TestHello(t *testing.T) {
client := testFC{}
Hello(client)
if client.callCount != 1 {
t.Fail("dependency not called")
}
}
当然,对于更复杂的依赖关系,您可以使用诸如嘲笑之类的工具或类似的工具,但您会明白。根据定义,UNIT测试集中于单个UNIT代码。测试包单元的最后一件事是从另一个包实例化一个类型。您应该能够模拟代码所依赖的所有内容。最好的方法是使用接口。