2017-03-22 66 views
4

我有以下測試方法,它使用從包中導入的函數。是否可以模擬從golang包中導入的函數?

import x.y.z 

func abc() { 
    ... 
    v := z.SomeFunc() 
    ... 
} 

是否有可能在golang中模擬SomeFunc()

+0

是。只需將'v'分配給你的模擬,並使用'v'而不是'z.SomeFunc'。可能你想讓'v'成爲一個全局的(並且重命名爲'zSomeFunc'。 – Volker

+0

Thanks Volker !!! – Pradeep

回答

10

是的,通過一個簡單的重構。創建函數類型的zSomeFunc變量,與z.SomeFunc初始化,並有代替z.SomeFunc()你的包來電:在測試中

var zSomeFunc = z.SomeFunc 

func abc() { 
    // ... 
    v := zSomeFunc() 
    // ... 
} 

您可以指定其他功能zSomeFunc,一個是在測試中定義的,爲所欲爲的測試希望它。

例如:

func TestAbc(t *testing.T) { 
    // Save current function and restore at the end: 
    old := zSomeFunc 
    defer func() { zSomeFunc = old }() 

    zSomeFunc = func() int { 
     // This will be called, do whatever you want to, 
     // return whatever you want to 
     return 1 
    } 

    // Call the tested function 
    abc() 

    // Check expected behavior 
} 

參閱本站/可能重複: 你可以做Testing os.Exit scenarios in Go with coverage information (coveralls.io/Goveralls)

+0

Thanks @icza for the pointers。它像一個魅力一樣工作 – Pradeep

3

有一件事情是這樣的:

import x.y.z 

var someFunc = z.SomeFunc 

func abc() { 
    ... 
    v := someFunc 
    ... 
} 

並在測試文件中,可以做到這一點。

func Test_abc() { 
    someFunc = mockFunc 
    abc() 
} 

但要確保你在並行的方式做到這一點,如果你有多個TestXxx功能調用abc或設置someFunc您可以使用structsomeFunc場的更好。

+0

值得注意的是,你可以使用參數' p 1'到'go test'來強制所有測試以串行方式運行而不是平行運行。 – Kaedys

2

有功能指針和猴子修補它是這樣做的。但是當你使用多個函數來模擬時,你將會得到一個數字函數指針,而且不必要的你只能用函數指針調用函數。

更好的和推薦的想法有一個接口,並使你的函數作爲實現接口的結構的一部分。一旦完成,你可以使用一些可用的好工具來生成模擬。

我一直用這個: mockgen -source myModule.go -package mypackage的-destination myModuleMock.go

您可以通過安裝它:有獲得github.com/golang/mock

相關問題