模拟一个内部函数(甚至更深入),以便在go中进行测试



有办法做到这一点吗?我想从另一个函数调用中模拟函数调用的响应。示例

main.go

type Crs struct {}
func (cr crs)TheFunction() error {
// Some code
_ := ToMockResponse(hello string)
return nil
}
func ToMockResponse() error {
return somerror
}

和测试文件

main_test.go

func TestTheFunction(t *testing.T) {
cr = Crs{}
mockInstance = new(randomMock)
mockInstance.On("ToMockResponse").Return(nil)
err := cr.TheFunction()
assert.NoError(t, err)
}
我不确定我所做的是否正确。我想要实现的是,我只是想有一个模拟响应的ToMockResponse每当它被调用内部的函数

我已经看过并阅读了大部分教程,但它们都显示了来自类的方法的Mock响应。但是没有函数到函数的模拟示例。希望您能提供一个解决方案。

不考虑是否应该这样做,并假设您有一个合理的理由这样做,模拟函数的一种方法是通过间接级别使用它们。然后,您可以在您的间接中为测试的目的替换一个合适的替代方案。

接口是实现这一目标的一种方法,但是GoLang支持函数作为值,因此另一种方法是使用适当函数类型的简单变量:

适应您的示例,这可能类似于:

var toMockResponse = ToMockResponse
func (cr crs)TheFunction() error {
// Some code
_ := toMockResponse(hello string)
return nil
}
func ToMockResponse() error {
return somerror
}

和你的测试:

func TestTheFunction(t *testing.T) {
cr = Crs{}
ofn := toMockResponse
toMockResponse = func(string) error { return nil }
defer func() { toMockResponse = ofn }()
err := cr.TheFunction()
assert.NoError(t, err)
}

我已经假设你需要导出ToMockResponse;函数变量故意而不是被导出,这样它就不能在包本身之外被操作。

如果被重定向的函数是本身未导出,拒绝使用导出与非导出符号的大小写差异来区分它们的能力,那么您可能需要在命名时更有创意一些。例如,一个名为toMockResponseFn的变量

脚注

ofn是"原始功能"的助记符。在更复杂的测试中,您可以通过为所需的每个ofn创建一个作用域来保留该模式(defer操作的是包含函数,而不是作用域):

{
ofn := toMockResponse
toMockResponse = func(string) error { return nil }
defer func() { toMockResponse = ofn }()
}
{
ofn := now
now = func() time.Time { return time.Date(..etc..) }
defer func() { now = ofn }()
}

最新更新