亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

我可以模擬一個帶有需要使用的指針參數的函數嗎

我可以模擬一個帶有需要使用的指針參數的函數嗎

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 關注
  • 188 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號