Unit testing 戈朗接口公司;嘲笑
我很难在Go中编写单元测试,因为外部库不公开接口(因此不可模仿),而只公开纯函数。即使是大公司也喜欢,所以我想知道我的方法是否足够好。Unit testing 戈朗接口公司;嘲笑,unit-testing,go,Unit Testing,Go,我很难在Go中编写单元测试,因为外部库不公开接口(因此不可模仿),而只公开纯函数。即使是大公司也喜欢,所以我想知道我的方法是否足够好。 如果库提供接口s而不是只包含函数的包来让用户模拟它们,这不是一个好的做法吗 到目前为止,我提出的解决方案是用接口的实现来包装这些包,但这似乎太多工作了 我举了一个例子。我的函数可以是这样的 func AnyFunction() error { sess := session.Get("blabla") // logic in here... }
如果库提供
接口
s而不是只包含函数的包来让用户模拟它们,这不是一个好的做法吗
到目前为止,我提出的解决方案是用接口的实现来包装这些包,但这似乎太多工作了
我举了一个例子。我的函数可以是这样的
func AnyFunction() error {
sess := session.Get("blabla")
// logic in here...
}
其中session是一个导入的包,它返回一个struct
。我无法模拟包会话
。
对于本例,我将编写一个带有实现的SessionInterface
,该实现在内部调用session
例:
对于我现在的测试,我可以模拟SessionInterface并将其注入到我的代码中,这是一个非常常见的解决方案,在可维护性和可测试性之间取得了很好的平衡 我的想法是,您的代码是针对一个接口编程的,正好有两种实现:
- “prod”版本即您正在测试的库
- 测试版本,实现接口的存根
插头:
我已经写了关于这个问题的文章,你在这里做的事情是正确的,这是语言设计者有意识的决定 Go的理念是,您的代码应该“拥有”这些接口,而不是库。在像C#和Java这样的语言中,库预先定义了它们的接口,而不知道消费者真正需要什么。(可能它们包含的方法太多,也可能太少。)在Go中,因为消费者实际上“拥有”了接口,所以您有权指定在最小的接口中实际需要存在哪些方法,而程序需求的更改意味着您也可以更改接口
现在在这个特定的情况下,在可测试性的函数前面创建适配器似乎是奇怪的,但是考虑另一种选择:如果<代码> session >()(代码)>是接口或结构的一种方法,而不是函数,它将迫使所有库用户实例化一个虚拟对象以调用该方法。并不是每个人都会假装出来——他们更容易说,想(像你一样)编写适配器的消费者有权编写适配器,而那些不想编写适配器的消费者可以很高兴地忽略它们。
“库提供接口不是一个好的做法”-如果不需要的话就不会。在Go中,接口实现是隐式的,因此接口通常是在使用它们的地方定义的,而不是在实现它们的地方定义的。也许本文对您来说很有趣:您也可以简单地使用测试可以更改的函数变量,请看,模拟对于测试来说通常是个坏主意。假货和存根在“测试的辨别力增强”的意义上通常“更好”。type SessionInterface interface {
Get(s string) Session
}
type mySessionImpl struct {}
func (me *mySessionImpl) Get(s string) Session {
return session.Get(s)
}