一尘不染

Golang接口和模拟

go

由于外部库不公开接口(因此不是可模拟的),而仅公开纯函数,因此我很难在Go中编写单元测试。即使像Google这样的公司也没有,所以我想知道我的方法是否足够好。库interface不是提供s而不是仅提供函数的包以便用户模拟它们的好习惯吗?

到目前为止,我想到的解决方案是将这些程序包与接口的实现包装在一起,但这似乎工作量太大。

我举一个例子。我的功能可能看起来像这样

func AnyFunction() error {
    sess := session.Get("blabla")
    // logic in here...
}

其中session是一个导入的包,返回struct。我不能嘲笑包裹session。对于这种情况,我将编写一个SessionInterface带有内部调用session的实现。

例如:

type SessionInterface interface {
    Get(s string) Session
}

type mySessionImpl struct {}
func (me *mySessionImpl) Get(s string) Session {
  return session.Get(s)
}

现在,对于我的测试,我可以模拟SessionInterface并将其注入我的代码中


阅读 197

收藏
2020-07-02

共1个答案

一尘不染

您在这里做的正确,这是语言设计师的明智决定。

Go的理念是您的代码应“拥有”那些接口,而不是库。在诸如C#和Java之类的语言中,库预先定义了它们的接口,而不真正知道使用者的实际需求。(也许它们包含的方法太多或太少。)在Go中,由于使用者有效地“拥有”了接口,因此您有权指定最小接口中实际需要存在哪些方法,并更改程序要求。表示您还可以更改界面。

现在,在这种特殊情况下,为实现可测试性而在函数之前创建适配器似乎很奇怪,但请考虑另一种选择:如果session.Get()是接口或结构的方法而不是函数,它将迫使所有库使用者实例化一个虚拟对象以调用该方法。并不是每个人都会伪造出来的-
对他们来说,说想要(像您一样)的消费者有权编写适配器,而那些不能幸福地忽略它们的消费者则更容易。

2020-07-02