【发布时间】:2023-03-05 02:46:01
【问题描述】:
我在 Go 中为一个相当常见的用例/模式编写单元测试时遇到了麻烦。
想象一下,如果你愿意的话,是这样的:
package main
type Resource struct {
name string
}
type ResourceManager interface {
GetResource(id string) (*Resource, error)
GetAllResources() ([]*Resource, error)
}
type ResourceManagerImpl struct {
}
func (r *ResourceManagerImpl) GetResource(id string) (*Resource, error) {
resource := &Resource{}
var err error
// fetch resource.
// ...
return resource, err
}
func (r *ResourceManagerImpl) GetAllResources() ([]*Resource, error) {
var resources []*Resource
var err error
// for _, id := range ids {
// resource = r.GetResource(id)
// resources = append(resources, resource)
// }
return resources, err
}
让GetAllResources 根据需要反复调用GetResource 是一种常见模式。
我可以使用gomock 或testify 来测试GetResource 的所有排列。但是,在测试GetAllResource 时,我想模拟GetResource。否则,测试将成为一场噩梦。如果 Java 使用部分模拟,这就是在 easymock 或 mockito 中执行此操作的方式。但是,尚不清楚如何在 Golang 中实现相同的目标。
具体来说,我找不到如何部分模拟struct。大多数建议都围绕着打破structs,但在这种情况下,struct 已经处于最低限度。为了测试,不要破坏ResourceManager 接口(分为单接口和多接口)似乎是一个公平的要求,因为这没有多大意义,而且充其量是笨拙的,并且随着更多这样的方法进入,也不能很好地扩展界面。
【问题讨论】:
标签: unit-testing go testing mocking go-interface