【发布时间】:2019-05-15 02:47:50
【问题描述】:
我正在尝试在 Go 中为现有服务实现单元测试,该服务使用连接池结构和现有库中的连接结构(调用这些 LibraryPool 和 LibraryConnection)连接到外部服务。
为了使用这些,主代码中的服务函数使用一个唯一的全局池实例,它有一个GetConnection() 方法,如下所示:
// Current Main Code
var pool LibraryPool // global, instantiated in main()
func someServiceFunction(w http.ResponseWriter, r *http.Request) {
// read request
// ...
conn := pool.GetConnection()
conn.Do("some command")
// write response
// ...
}
func main() {
pool := makePool() // builds and returns a LibraryPool
// sets up endpoints that use the service functions as handlers
// ...
}
我想在不连接到外部服务的情况下对这些服务功能进行单元测试,因此我想模拟 LibraryPool 和 LibraryConnection。为此,我正在考虑将主代码更改为以下内容:
// Tentative New Main Code
type poolInterface interface {
GetConnection() connInterface
}
type connInterface interface {
Do(command string)
}
var pool poolInterface
func someServiceFunction(w http.ResponseWriter, r *http.Request) {
// read request
// ...
conn := pool.GetConnection()
conn.Do("some command")
// write response
// ...
}
func main() {
pool := makePool() // still builds a LibraryPool
}
在测试中,我将使用这些接口的模拟实现MockPool 和MockConnection,并且将使用MockPool 实例化全局pool 变量。我将在setup() 函数中实例化这个全局pool,在TestMain() 函数内部。
问题是在新的主代码中,LibraryPool 没有正确实现poolInterface,因为GetConnection() 返回一个connInterface 而不是LibraryConnection(即使@ 987654339@ 是connInterface 的有效实现。
进行此类测试的好方法是什么?顺便说一下,主要代码也很灵活。
【问题讨论】:
-
只需在 LibraryPool 周围创建一个瘦包装器,该包装器将实现 poolInterface 接口。包装器的 GetConnection 只是委托给包含的 LibraryPool。 play.golang.com/p/TmRrtR_QS_u
标签: unit-testing go