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 乌班图ip地址配置及远程SSH
  • ¥15 怎么让点阵屏显示静态爱心,用keiluVision5写出让点阵屏显示静态爱心的代码,越快越好
  • ¥15 PSPICE制作一个加法器
  • ¥15 javaweb项目无法正常跳转
  • ¥15 VMBox虚拟机无法访问
  • ¥15 skd显示找不到头文件
  • ¥15 机器视觉中图片中长度与真实长度的关系
  • ¥15 fastreport table 怎么只让每页的最下面和最顶部有横线
  • ¥15 java 的protected权限 ,问题在注释里
  • ¥15 这个是哪里有问题啊?