gpt4 book ai didi

unit-testing - Go 中的模拟函数

转载 作者:IT老高 更新时间:2023-10-28 12:56:58 24 4
gpt4 key购买 nike

我对依赖关系感到困惑。我希望能够用模拟函数调用替换一些函数调用。这是我的代码片段:

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])
}
}

我希望能够在不通过 h​​ttp 实际获取页面的情况下测试 downloader() - 即通过模拟 get_page (更容易,因为它只返回页面内容为字符串)或 http.Get().

我找到了 this thread这似乎是一个类似的问题。 Julian Phillips 展示他的图书馆,Withmock作为解决方案,但我无法让它工作。这是我的测试代码的相关部分,老实说,这对我来说主要是 cargo 崇拜代码:

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
}

测试输出如下:

ERROR: Failed to install '_et/http': exit status 1 output: can't loadpackage: package _et/http: found packages http (chunked.go) and main(main_mock.go) in
/var/folders/z9/ql_yn5h550s6shtb9c5sggj40000gn/T/withmock570825607/path/src/_et/http

Withmock 能否解决我的测试问题?我应该怎么做才能让它工作?

最佳答案

就我个人而言,我不使用 gomock(或任何模拟框架;没有它,Go 中的模拟非常容易)。我要么将依赖项作为参数传递给 downloader() 函数,要么将 downloader() 设为类型上的方法,并且该类型可以保存 get_page 依赖:

方法一:通过get_page()作为downloader()的参数

type PageGetter func(url string) string

func downloader(pageGetterFunc PageGetter) {
// ...
content := pageGetterFunc(BASE_URL)
// ...
}

主要:

func get_page(url string) string { /* ... */ }

func main() {
downloader(get_page)
}

测试:

func mock_get_page(url string) string {
// mock your 'get_page()' function here
}

func TestDownloader(t *testing.T) {
downloader(mock_get_page)
}

方法2:使download()成为Downloader类型的方法:

如果您不想将依赖项作为参数传递,您还可以将 get_page() 设为类型的成员,并将 download() 设为该类型的方法,然后可以使用 get_page:

type PageGetter func(url string) string

type Downloader struct {
get_page PageGetter
}

func NewDownloader(pg PageGetter) *Downloader {
return &Downloader{get_page: pg}
}

func (d *Downloader) download() {
//...
content := d.get_page(BASE_URL)
//...
}

主要:

func get_page(url string) string { /* ... */ }

func main() {
d := NewDownloader(get_page)
d.download()
}

测试:

func mock_get_page(url string) string {
// mock your 'get_page()' function here
}

func TestDownloader() {
d := NewDownloader(mock_get_page)
d.download()
}

关于unit-testing - Go 中的模拟函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19167970/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com