如何使用未导出结构的功能

时间:2019-10-07 11:38:03

标签: go

我有一个程序包,其中未导出结构并导出了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()

}

1 个答案:

答案 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代码。测试包单元的最后一件事是从另一个包实例化一个类型。您应该能够模拟代码所依赖的所有内容。最好的方法是使用接口。