go - 如何使用未导出结构体的函数

标签 go

我有一个包,其中未导出结构并导出了用于创建它的新函数以及在此结构上运行的导出函数(例如此处建议的: Return an unexported type from a function )。 如果我在调用 New 的同一位置运行该函数,我可以运行包函数,但无法将此实体发送到另一个函数。 无需将所有代码放在一个函数中即可实现此行为的最佳方法是什么

例如,这个有效:

client := package.New()

client.Foo()

但这行不通:

client := package.New()

hello(client)


func hello(client interface{}) {

    client.Foo()

}

最佳答案

您的 hello 函数本质上需要的是具有 Foo 函数的东西。这就是 go 有接口(interface)的原因。返回未导出的类型没有任何问题(事实上,这很常见,而且通常是正确的做法)。我要做的是这样的:

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")
    }
}

当然,对于更复杂的依赖关系,您可以使用诸如mockgen之类的工具或类似的东西,但您明白了。根据定义,UNIT 测试侧重于单个代码单元。测试包单元所需要做的最后一件事是实例化另一个包中的类型。您应该能够模拟代码所依赖的所有内容。最好的方法是接口(interface)。

关于go - 如何使用未导出结构体的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58268837/

相关文章:

unit-testing - 如何对Gin Gonic中的cookie进行单元测试提取

go - 如何在 go 中使用我的导入包的结构作为类型

go - 具有接口(interface)类型和结构指针的 channel 作为具体类型

go - 我可以传递一个字符串作为 bufio.ReadString() 的分隔符吗?

go - Windows exec runner 无法克隆 git repo

go - AWS Cognito 的 SMS 多因素身份验证返回无效代码或身份验证状态

rest - 如何将 UINT(不是 uint64 或 uint32)与字符串进行比较

go - 如何动态决定处理任务的 goroutines 数量

go - 有没有办法在 Go 中进行基于 socks 的动态端口转发,就像 SSH 中的 -d 开关一样?

inheritance - 用于约束和继承集的接口(interface)