【发布时间】:2020-04-14 18:02:05
【问题描述】:
当我尝试对如下函数进行单元测试时,extern_pkg 是要模拟的外部包:
import "extern_pkg"
func MyFunc() {
...
extern_pkg.F()
}
func main() {
MyFunc()
}
我阅读了一些博客,它们似乎都是通过使用依赖注入修改产品代码来实现的。例如如下:
type exter interface {
F()
}
func MyFunc(e exter) {
...
e.F()
}
type extpkg struct{}
func (extpkg) F() {extern_pkg.F()}
func main() {
epkg := extpkg{}
MyFunc(epkg)
}
然后在测试代码中,创建一个满足exter接口的mock对象,并作为参数传递给MyFunc。
我的问题是:
- 如果
MyFunc函数包含许多要模拟的外部包,我是否需要DI每个作为函数参数?函数所依赖的任何全局变量也是如此吗?
var global_var
func MyFunc() {
...
extern_pkg1.F()
...
extern_pkg2.G()
...
extern_pkg3.H()
...
global_var
}
- 有没有办法避免修改产品代码?
谢谢!
【问题讨论】:
-
这是一个干净的设计问题,因为问题代码目前与第 3 方外部依赖项紧密耦合
-
你不能模拟或注入一个包,这不是包的工作方式。您可以模拟或注入类型和函数,但不能模拟包 - 没有可以传递的“包值”。
-
@Adrian 好的,那么我的意图是模拟包中的类型和函数。对我的问题有什么想法吗?
-
至 Q1:是的,您需要 DI 每一个。如果您有一个具有许多依赖项的函数,那是一种代码味道,表明它应该被重构。 Q2:不清楚你在问什么。如果您的产品代码无法按原样测试,那么您必须对其进行修改以进行测试,对吧?
标签: unit-testing go dependency-injection