2 回答
TA贡献2037条经验 获得超6个赞
更新:我收回我之前的回答。不要跨包导出接口。让您的函数返回具体类型,以便允许消费者创建自己的接口并根据需要进行覆盖。
请参阅:https ://github.com/golang/go/wiki/CodeReviewComments#interfaces HatTip:@rocketspacer
我通常也将我的测试编码在与我的包代码不同的包中。这样,我只能看到我导出的内容(如果导出太多,你有时会看到你弄乱了什么)。
按照本指南,为了测试您的包,过程将是:
使用 func 像往常一样创建复杂对象
根据需要在内部使用接口(例如,Car <- Object -> House)
只导出你的混凝土,而不是接口
在测试期间,指定一个测试方法,该方法采用您的具体方法的测试接口,并根据需要更改您的接口。您在测试包中创建此测试接口。
下面的原始答案供后代使用
仅导出您的界面,而不是您的具体类型。并添加一个New()
构造函数,以便人们可以从您的包中实例化一个符合接口的默认实例。
package validator
type Validator interface {
Validate(doc interface{}) (valid bool, err error)
ValidateString(doc string) (valid bool, err error)
}
func New() Validator {
return &validator{}
}
type validator struct {
schemaLoader gojsonschema.JSONLoader
validationError error
}
func (v *validator) Validate(doc interface{}) (valid bool, err error) {
...
}
func (v *validator) ValidateString(doc string) (valid bool, err error) {
...
}
这使您的 API 包保持干净,仅包含Validator和New()导出。
您的消费者只需要了解界面。
package main
import "foo.com/bar/validator"
func main() {
v := validator.New()
valid, err := v.Validate(...)
...
}
这让您的消费者可以遵循依赖注入模式并New()在其使用之外实例化(调用),并将实例注入到他们使用它的任何地方。这将允许他们在测试中模拟接口并注入模拟。
或者,消费者可以不那么关心,只写上面的主要代码,简短而甜美并完成工作。
TA贡献1780条经验 获得超1个赞
恕我直言,这是一个很好的解决方案。接口在测试和重新实现时为您提供更多自由。我经常使用接口,我从不后悔(尤其是在测试时),即使它是一个单一的实现(在我的情况下,大部分时间)。
您可能对此感兴趣:http : //relistan.com/writing-testable-apps-in-go/
- 2 回答
- 0 关注
- 147 浏览
添加回答
举报