回答

收藏

Go 中的模拟函数

技术问答 技术问答 189 人阅读 | 0 人回复 | 2023-09-12

我对依赖感到困惑。我希望用模拟函数来代替一些函数。这是我的代码片段:( z. h4 W. S" y. q

    6 e( m- {* C- R+ _8 `6 q1 g
  • 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   }code]希望能在这里downloader()不实际通过 http在获取页面时进行测试- 通过模拟get_page(更容易,因为它只返回页面内容作为字符串)或http.Get().
    ' q. l# H/ n, m2 t) A
  • 我发现这个线程似乎是关于类似的问题。Julian Phillips 提出了他的库Withmock作为解决方案,但我不能让它工作。这是我测试代码的相关部分。说实话,这主要是货物崇拜代码:[code]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}1 v- C3 d: p/ E0 D: z
测试输出如下:
% ]' n* V; W3 I7 Z错误:无法安装_et/http:退出状态 1 输出:无法加载包:包 _et/http:在* X" p" A) I  U4 A
/var/folders/z在9/ 中找到包 http (chunked.go) 和 main (main_mock.go) ql_yn5h550s6shtb9c5sggj40000gn/T/withmock570825607/path/src/_et/http+ {) m. `+ [; t6 O1 T
Withmock 是我测试问题的解决方案吗?我该怎么办才能让它工作?
. f" ?- o7 o- l8 V1 _& k! O                                                                + J% Z* ?" W9 R$ p, |" w& M: N% r. B8 c
    解决方案:                                                                & v# @5 G" [8 A6 ^; X
                                                                就我个人而言,我不使用它gomock(或任何与此相关的模拟框架;没有它, Go 模拟很容易)。我要么依赖项目。downloader()作为参数传递给函数或downloader()在类型上创建一个方法,该类型可以保存get_page依赖项:% D. K+ p8 T& j/ ]; Z) c/ e1 V
方法一:get_page()作为参数传递downloader()
    type PageGetter func(url string) stringfunc downloader(pageGetterFunc PageGetter)      / ...    content := pageGetterFunc(BASE_URL)    // ...}' T8 [3 u' t. ~( f* a; {
主要的:
( [: Y; t% T* z$ `/ E5 ~" x2 D
    func get_page(url string) string { /* ... */ }func main()      downloader(get_page)}# y5 D) `8 r& D
测试:# d' ]4 s$ |, }* s) y& G' w
    func mock_get_page(url string) string      / mock your 'get_page()' function here}func TestDownloader(t *testing.T)    downloader(mock_get_page)}
    0 u, ~4 x5 T: h9 ^
方法 2:download()创建一种方法Downloader:如果不想以依赖项为参数传递,也可以创建get_page()一类成员,创建download()这种方法可以使用get_page:/ }; J0 G/ O  v- H
    type PageGetter func(url string) stringtype 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)   ...}
    0 O+ x4 P- v! j# L' J
主要的:
6 I. y3 i" f. G" Q  ~* H1 ]/ r
    func get_page(url string) string { /* ... */ }func main()      d := NewDownloader(get_page)    d.download()}
      N9 A1 Q6 {. \! r/ _) s
测试:
: P6 A0 H- O9 w
    func mock_get_page(url string) string      / mock your 'get_page()' function here}func TestDownloader()      d := NewDownloader(mock_get_page)    d.download()}
    ) U9 Y, `- V7 z( t/ G
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则