dtkvlj5386 2017-09-20 10:33
浏览 60
已采纳

Golang模拟函数被调用两次

I'm writing unit test for testing main.go and inside the function it's call Get function ( DeviceRepo.Get() ) twice then I would like to mock the Get function which return different but I can mock just first time when it called, So I have no idea how do I mock the Get function at the second time?

main.go:

type DeviceInterface interface {}
type DeviceStruct struct{}

var DeviceRepo repositories.DeviceRepoInterface =  &repositories.DeviceRepoStruct{}

func (d *DeviceStruct) CheckDevice(familyname string, name string, firmwareversion string) string {
deviceList, deviceListErr := DeviceRepo.Get(familyname, name, firmwareversion)

if deviceListErr != "" {
    return "some error"
}

if len(deviceList) == 0 {
    deviceList, _ := DeviceRepo.Get(familyname, name, "")

    if len(deviceList) > 0 {
        return "Invalid firmware version."
    } else {
        return "Unknown device."
    }
}

return "Success"
}

main_test.go:

  type MockGetDeviceList struct {
    returnResult []resources.DeviceListDataReturn
    returnError  string
  }

  func (m *MockGetDeviceList) Get(familyName string, name string, firmwareVersion string) ([]resources.DeviceListDataReturn, string) {
    return m.returnResult, m.returnError
  }

  func Test_CheckDevice_WrongFirmwareVersion(t *testing.T) {
   Convey("Test_CheckDevice_WrongFirmwareVersion", t, func() {
    familyNameMock := "A"
    nameMock := "A"
    firmwareVersionMock := "3"

    mockReturnData := []resources.DeviceListDataReturn{}

    mockReturnDataSecond := []resources.DeviceListDataReturn{
        {
            FamilyName:      "f",
            Name:            "n",
            FirmwareVersion: "1.0",
        },
    }

    deviceModel := DeviceStruct{}

    getDeviceList := DeviceRepo
    defer func() { DeviceRepo = getDeviceList }()
    DeviceRepo = &MockGetDeviceList{returnResult: mockReturnData}

    getDeviceList = DeviceRepo
    defer func() { DeviceRepo = getDeviceList }()
    DeviceRepo = &MockGetDeviceList{returnResult: mockReturnDataSecond}

    expectReturn := "Invalid firmware version."

    actualResponse := deviceModel.CheckDevice(familyNameMock, nameMock, firmwareVersionMock)

    Convey("Checking check-device wrong firmware version", func() {
        So(actualResponse, ShouldEqual, expectReturn)
    })
})
}

I would like to mock the Get function return []resources.DeviceListDataReturn{} at first time and then return []resources.DeviceListDataReturn{ { FamilyName: "f", Name: "n", FirmwareVersion: "1.0", }, } in the second time.

  • 写回答

1条回答 默认 最新

  • doucheng4660 2017-09-20 11:33
    关注

    For any function or method to act differently based on the call number, this info needs to be available in it.

    Easiest is to add and increment a counter on each call, and inside the function examine the counter's current value, and act differently depending on its value:

    type MockGetDeviceList struct {
        returnResult []resources.DeviceListDataReturn
        returnError  string
        getCount     int
    }
    
    func (m *MockGetDeviceList) Get(familyName string, name string,
        firmwareVersion string) ([]resources.DeviceListDataReturn, string) {
    
        m.getCount++
        if m.getCount == 1 {
            // First call:
            return nil, m.returnError
        }
        // Sencond and subsequent calls:
        return m.returnResult, ""
    }
    

    Another solution would be to replace the mock object / function after the first call, but this solution is harder to understand, more fragile and less maintainable.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 stm32流水灯+呼吸灯+外部中断按键
  • ¥15 将二维数组,按照假设的规定,如0/1/0 == "4",把对应列位置写成一个字符并打印输出该字符
  • ¥15 NX MCD仿真与博途通讯不了啥情况
  • ¥15 win11家庭中文版安装docker遇到Hyper-V启用失败解决办法整理
  • ¥15 gradio的web端页面格式不对的问题
  • ¥15 求大家看看Nonce如何配置
  • ¥15 Matlab怎么求解含参的二重积分?
  • ¥15 苹果手机突然连不上wifi了?
  • ¥15 cgictest.cgi文件无法访问
  • ¥20 删除和修改功能无法调用