Golang接口和嘲笑 [英] Golang interfaces & mocking

查看:44
本文介绍了Golang接口和嘲笑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于外部库不公开接口(因此不是可模拟的),而仅公开纯函数,因此我很难在Go中编写单元测试.甚至像 Google都不是的大,我想知道我的方法是否足够好.对于库来说,提供 interface 而不是仅提供函数的软件包以便用户模拟它们不是很好的做法吗?

I'm having hard times writing unit tests in Go due to external libraries which don't expose an interface (therefore not mockable) but only pure functions. Even big ones like Google don't, so I'm wondering whether my approach is good enough. Wouldn't be good practice for libraries to provide interfaces instead of packages with only functions in order to let the user mock them?

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

The solution I came up with until now is wrap these packages with an interface's implementation but that seem like too much work.

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

I come with an example. My function could look like this

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

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

where session is an imported package that returns a struct. I can't mock the package session. For this case I'm going to write a SessionInterface with an implementation, which internally calls session.

例如:

type SessionInterface interface {
    Get(s string) Session
}

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

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

For my tests now I can mock the SessionInterface and inject that one into my code

推荐答案

您在这里做的正确,这是语言设计师的自觉决定.

You're doing the right thing here, and this was a conscious decision on the part of the language designers.

Go的哲学是您的代码应拥有"那些接口,而不是库.在C#和Java之类的语言中,库在不真正了解用户实际需要什么的情况下预先定义了它们的接口.(也许它们包含的方法太多或太少.)在Go中,由于使用者有效地拥有"了接口,因此您有权指定最小接口中实际需要存在哪些方法,并更改程序要求.意味着您还可以更改界面.

The Go philosophy is that your code should "own" those interfaces, not the library. In languages like C# and Java, libraries define their interfaces up front, without really knowing what the consumer actually needs. (Maybe they include too many methods, or too few.) In Go, because the consumer effectively "owns" the interfaces, you're empowered to specify which methods actually need to be present in a minimal interface, and changes in your program requirements mean that you can also change the interface.

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

Now in this particular case it might seem strange to create an adapter in front of a function for testability, but consider the alternative: if session.Get() were a method of an interface or struct, instead of a function, it would force all library consumers to instantiate a dummy object in order to call the method. Not everyone is going to fake it out---it's easier for them to say that the consumers who want to (like you) are empowered to write adapters, and those that don't can blissfully ignore them.

这篇关于Golang接口和嘲笑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆