繁体   English   中英

作证模拟 function 返回 function

[英]Testify Mock a function return inside a function

我想模拟 function 的响应。 但是这个 function 位于或调用另一个 function 内部。 假设我有这个 function

// main.go
func TheFunction() int {
   // Some code
   val := ToMockResponse()
   return val
}

func ToMockResponse() int {
    return 123
}

现在在我的测试文件上

// main_test.go
func TestTheFunction(t *testing.T) {
    mockInstance = new(randomMock)
    mockInstance.On("ToMockResponse").Return(456)

    returned := TheFunction()
    assert.Equal(t, 456, returned)
}

正如您在 function TheFunction()中看到的那样,调用了 function ToMockResponse 现在我想测试TheFunction但我想模拟ToMockResponse的响应如何实现?

您应该考虑将第二个函数作为第一个的参数传递。

您可以选择几种方法。 您可以简单地将其作为参数传递。

func DoX(doY func()) {
   doY()
}

这很简单,但随着核心变得越来越复杂,效果并不理想。 更好的选择通常是使函数方法在结构上。

type X struct {
   Y Y
}

type Y interface {
   Do()
}

func (x *X) Do() {
   x.Y.Do()
}

然后可以用模拟代替Y。

假设我们有两个函数, executor()process() ,其中执行器 function 调用进程 function,

我们需要使用结构和接口编写如下所示的两个函数:

main.go如下图:

package main

import "fmt"

// A structure defined which will have a value of type processHandler(interface)
// This is helpful  to pass a structure instance of processData later(see in main function)
// This is required to pass mock instance also
type processDataHandler struct{ procData processHandler }

// Interface defined for process method
type processHandler interface {
    process() (int, string)
}

// structure on top of which executor method is getting called
type processData struct{}

// process method called by executor method
func (p processData) process() (int, string) {
    return 23, "test2"
}

// executor method which has "processDataHandler" as argument
func (e processDataHandler) executor() (int, string) {
    // Some code
    //process function call
    val, str_val := e.procData.process()
    if val == 23 {
        return 40, "success"
    }
    return 45, str_val
}

func main() {
    procData := processData{}
    dataHandle := processDataHandler{procData: procData}
    val1, val2 := dataHandle.executor()

    fmt.Println(val1)

    fmt.Println(val2)

}

main_test.go如下图:

package main

import (
    "testing"

    "github.com/stretchr/testify/assert"
    "github.com/stretchr/testify/mock"
)

//Define a mock insatnce
type processDataMock struct {
    mock.Mock
}

func (m *processDataMock) process() (int, string) {
    // this records that the method was called and passes in the value
    // it was called with
    args := m.Called()
    // it then returns whatever we tell it to return
    // in this case we are returing a integer type followed by a string type
    return args.Int(0), args.String(1)
}

//Test function for executor method
func TestExecutor(t *testing.T) {
    //define mock instance
    procMock := new(processDataMock)
    //Make process function to return 1 and "test" via mock
    procMock.On("process").Return(1, "test")
    //create a processDatahandler with mock instance
    handler := processDataHandler{procData: procMock}
    //call executor function which inturn mocks process via "procMock.On" above
    a, b := handler.executor()

    assert.Equal(t, 45, a)
    assert.Equal(t, "test", b)

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM