我正在编写单元测试来测试 main.go ,并且在函数内部调用 Get 函数( DeviceRepo.Get() )两次,然后我想模拟返回不同的 Get 函数,但我可以在第一次调用时进行模拟,所以我不知道如何第二次模拟 Get 函数?
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"
}
Run Code Online (Sandbox Code Playgroud)
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)
})
})
}
Run Code Online (Sandbox Code Playgroud)
我想第一次模拟 Get 函数 return []resources.DeviceListDataReturn{} 然后 return []resources.DeviceListDataReturn{ { FamilyName: "f", Name: "n", FirmwareVersion: "1.0", }, }在第二次。
您可以使用https://pkg.go.dev/github.com/stretchr/testify/mock#Call.Once
mock.On("Get", mock.Anything).Return(mockReturnData).Once()
mock.On("Get", mock.Anything).Return(mockReturnData2).Once()
Run Code Online (Sandbox Code Playgroud)
或者如果你知道你可以传递什么参数那么你可以这样做
mock.On("Get", "lastName", "name", "version").Return(mockReturnData)
mock.On("Get", "lastName_2", "name_2", "version_2").Return(mockReturnData2)
Run Code Online (Sandbox Code Playgroud)
对于根据调用号执行不同操作的任何函数或方法,需要在其中提供此信息。
最简单的方法是在每次调用时添加和递增计数器,并在函数内部检查计数器的当前值,并根据其值采取不同的操作:
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, ""
}
Run Code Online (Sandbox Code Playgroud)
另一种解决方案是在第一次调用后替换模拟对象/函数,但这种解决方案更难理解、更脆弱且更难维护。
| 归档时间: |
|
| 查看次数: |
9532 次 |
| 最近记录: |