为了账号安全,请及时绑定邮箱和手机立即绑定

我可以模拟一个带有需要使用的指针参数的函数吗

我可以模拟一个带有需要使用的指针参数的函数吗

Go
白衣染霜花 2023-08-14 16:15:56
假设我们有一个库提供了一个 Double 函数来将整数加倍,我们使用指针 i 来获取结果值而不是通过返回:package apitype Action interface {    Double(i *int) error}type NUM struct{}func (n NUM) Double(i *int) error {    *i *= 2    return nil}在我们的主函数中,我们使用这个库来完成我们的任务。像这样:package appimport (    "fmt"    "github.com/hotsnow/api")func main() {    j := job{a: &api.NUM{}}    d := j.task(3)    fmt.Println(3, d)}type job struct {    a api.Action}// double mefunc (j job) task(i int) int {    j.a.Double(&i)    return i}现在我们需要测试task()函数,我们怎样才能通过模拟Double函数获得指针返回呢?这是测试:package appimport (    "github.com/golang/mock/gomock"    "github.com/hotsnow/mocks"    "testing")func TestReq(t *testing.T) {    ctrl := gomock.NewController(t)    defer ctrl.Finish()    m := mocks.NewMockAction(ctrl)    m.EXPECT().Double(gomock.Any()).Return(nil)    j := job{a: m}    got := j.task(3)    if got != 6 {        t.Errorf("got = %#v; want 6", got)    }}
查看完整描述

3 回答

?
江户川乱折腾

TA贡献1851条经验 获得超5个赞

您可以为此使用 gomock setarg函数

yourPackage.EXPECT().insert(&pointer).SetArg(0, newPointer)


查看完整回答
反对 回复 2023-08-14
?
翻过高山走不出你

TA贡献1875条经验 获得超3个赞

您可以使用提供的Eq()matcher来实现此目的,它在内部调用reflect.DeepEqual()预期值和实际值;根据此方法的文档:

如果使用 Go 的 == 运算符相等或者它们指向深度相等的值,则指针值深度相等

假设我们有一个函数依赖于带有指针参数的接口方法:

package resource


type ServiceRequest struct {

    Name  string

    Owner *string // this is a pointer so it can be omitted with `nil`

}


type Model struct {

    // resource model...

}


type ResourceService interface {

    Fetch(req *ServiceRequest) (Model, error)

}


type getResourceHandler struct {

    resourceService ResourceService

}


type GetResourceEvent struct {

    Resource string

    Owner    *string

}


func NewResourceHandler(resourceService ResourceService) *getResourceHandler {

    return &getResourceHandler{resourceService}

}


func (h *getResourceHandler) Handle(event GetResourceEvent) (Model, error) {

    return h.resourceService.Fetch(&ServiceRequest{event.Resource, event.Owner})

}

我们可以Eq()在针对生成的接口模拟设置期望时使用匹配器ResourceService:


package test


import (

    "testing"


    "github.com/golang/mock/gomock"

    "github.com/stretchr/testify/assert"


    "github.com/org/repo/internal/mock"

    "github.com/org/repo/internal/resource"

)


func optionalString(str string) *string {

    return &str

}


func Test_GetResourceHandler_ReturnsResultFromService(t *testing.T) {

    resourceName := "my-resource"

    owner := optionalString("Joe Bloggs")

    resourceReq := &resource.ServiceRequest{resourceName, owner}

    event := resource.GetResourceEvent{resourceName, owner}

    model := resource.Model{ /* fields here... */ }


    ctrl := gomock.NewController(t)

    mockResourceService := mock.NewMockResourceService(ctrl)

    handler := resource.NewResourceHandler(mockResourceService)


    mockResourceService.EXPECT().Fetch(gomock.Eq(resourceReq)).Return(model, nil)


    res, err := handler.Handle(event)


    assert.Nil(t, err)

    assert.Equal(t, model, res)

}

如果您在测试或被测单元中更改服务请求的内容,您将看到测试不再通过。否则,尽管测试和被测单元有各自的指向单独ServiceRequest{}值的指针,它仍然会通过。


查看完整回答
反对 回复 2023-08-14
?
慕运维8079593

TA贡献1876条经验 获得超5个赞

看来你不必使用gomock来测试该task方法。


既然你有一个接口,为什么不直接创建该接口的模拟实现,例如:


type dummy struct{

    callCount int

}


func (d *dummy) Double(i *int) error {

    d.callCount++

    return nil

}


d := dummy{}

j := job{a: &d}

got := j.task(3)

if d.callCount != 1 {

    // XXX

}


查看完整回答
反对 回复 2023-08-14
  • 3 回答
  • 0 关注
  • 138 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信