我对依赖性感到困惑。我希望能够用模拟函数替换一些函数调用。这是我的代码片段:
func get_page(url string) string {
get_dl_slot(url)
defer free_dl_slot(url)
resp, err := http.Get(url)
if err != nil { return "" }
defer resp.Body.Close()
contents, err := ioutil.ReadAll(resp.Body)
if err != nil { return "" }
return string(contents)
}
func downloader() {
dl_slots = make(chan bool, DL_SLOT_AMOUNT) // Init the download slot semaphore
content := get_page(BASE_URL)
links_regexp := regexp.MustCompile(LIST_LINK_REGEXP)
matches := links_regexp.FindAllStringSubmatch(content, -1)
for _, match := range matches{
go serie_dl(match[1], match[2])
}
}
我希望能够测试 downloader()
而无需实际通过 http 获取页面 - 即通过 get_page
(更容易,因为它只返回页面内容作为字符串)或 http.Get()
。
我发现 这个线程 似乎是关于类似的问题。 Julian Phillips 展示了他的库 Withmock 作为解决方案,但我无法让它工作。这是我的测试代码的相关部分,老实说,这对我来说主要是货物崇拜代码:
import (
"testing"
"net/http" // mock
"code.google.com/p/gomock"
)
...
func TestDownloader (t *testing.T) {
ctrl := gomock.NewController()
defer ctrl.Finish()
http.MOCK().SetController(ctrl)
http.EXPECT().Get(BASE_URL)
downloader()
// The rest to be written
}
测试输出如下:
错误:无法安装“_et/http”:退出状态 1 输出:无法加载包:包 _et/http:在中找到包 http (chunked.go) 和 main (main_mock.go)
/var/folders/z9/ql_yn5h550s6shtb9c5sggj40000gn/T/withmock570825607/path/src/_et/http
Withmock 可以解决我的测试问题吗?我应该怎么做才能让它工作?
原文由 GolDDranks 发布,翻译遵循 CC BY-SA 4.0 许可协议
就个人而言,我不使用
gomock
(或与此相关的任何模拟框架;没有它在 Go 中模拟非常容易)。我要么将依赖项传递给downloader()
函数作为参数,要么我将downloader()
一个类型的方法,并且该类型可以保存get_page
依赖:方法一:传递
get_page()
作为downloader()
的参数主要的:
测试:
方法2:制作
download()
一个类型的方法Downloader
:如果您不想将依赖项作为参数传递,您还可以制作
get_page()
类型的成员,并制作download()
该类型的方法,然后可以使用get_page
:主要的:
测试: