Golang接口和模拟

时间:2019-03-11 15:41:37

标签: unit-testing go

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

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

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

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

其中session是一个导入的程序包,它返回struct。我无法嘲笑包session。 对于这种情况,我将编写一个SessionInterface及其实现,该实现在内部调用会话。

例如:

type SessionInterface interface {
    Get(s string) Session
}

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

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

1 个答案:

答案 0 :(得分:1)

IMO这是一种超级通用的解决方案,在可维护性和可测试性之间取得了很好的平衡。

我认为这是您的代码正在对接口进行编程,并且恰好有两个实现:

  • “产品”版本,即您正在测试的库
  • 测试版本,实现接口的存根

使用这种方法,存根只能沿接口协定验证您的服务及其依赖关系边界,它可以确保与存根库的组件协作/集成很少或没有。以我的经验,这种方法很棒,是我个人的喜好。我发现这很重要,尽管要进行1或2个更高级别的测试,以确保您的组件可以成功初始化并与库的“ prod”版本进行交互。


插件:

我已经写过关于这个确切的问题https://medium.com/dm03514-tech-blog/you-are-going-to-need-it-using-interfaces-and-dependency-injection-to-future-proof-your-designs-2cf6f58db192