2017-03-22 109 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

相关问题