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 phython如何实现以下功能?查找同一用户名的消费金额合并—
  • ¥15 孟德尔随机化怎样画共定位分析图
  • ¥18 模拟电路问题解答有偿速度
  • ¥15 CST仿真别人的模型结果仿真结果S参数完全不对
  • ¥15 误删注册表文件致win10无法开启
  • ¥15 请问在阿里云服务器中怎么利用数据库制作网站
  • ¥60 ESP32怎么烧录自启动程序
  • ¥50 html2canvas超出滚动条不显示
  • ¥15 java业务性能问题求解(sql,业务设计相关)
  • ¥15 52810 尾椎c三个a 写蓝牙地址