英文:
How to use gomock to make a mocked function return different results on subsequent calls?
问题
我正在使用gomock来模拟在被测试的函数中调用的http函数。虽然对于一次调用它运行得很好,但当我想在第二次调用时返回不同的结果时,它似乎再次调用了第一个函数(请参见下面的代码)。该函数会调用第一个模拟函数(在calls切片中)n次,所以我的问题是:如何使用gomock使模拟函数在后续调用中返回不同的结果?我参考了这个stackoverflow的帖子进行了尝试。
到目前为止,我有以下代码:
ctrl := gomock.NewController(t)
defer ctrl.Finish()
// Mock http client
mockHttp := mock_http.NewMockHttp(ctrl)
// 设置模拟调用的顺序
var calls []*gomock.Call
for i := 0; i < len(tc.mockHttpResps); i++ {
// 注意:tc.mockHttpResps[i] 是一个 *http.Response{}
fn := mockHttp.EXPECT().Post(gomock.Any(), gomock.Any(),gomock.Any()).Return(tc.mockHttpResps[i], tc.mockHttpErrs[i]).Times(1)
calls = append(calls, fn)
}
gomock.InOrder(
calls...
)
但是它会产生以下错误:
Unexpected call to *mock_rpc.MockHttp.Post because [function] has already been called the max number of times
如果我尝试将调用设置为.AnyTimes()
,那么错误就会消失,但第一个模拟函数仍然被多次调用。然后我会遇到其他错误,比如EOF
,因为http.Response的body被读取了两次,这是可以预料的。
注意:我尝试按照链接的帖子中的方法进行操作,但结果仍然出现相同的错误。
英文:
I am using gomock to mock an http function that is called within the function under test. While it works great for one call it seems to call the first function again when I want to return a different result on the second call (see code below). The function calls the first mocked function (in calls slice) n number of times, so my question is: How can I use gomock to make a mocked function return different results on subsequent calls? I used this stackoverflow post for inspiration.
This is what I have until now:
ctrl := gomock.NewController(t)
defer ctrl.Finish()
// Mock http client
mockHttp := mock_http.NewMockHttp(ctrl)
// set up order of mock calls
var calls []*gomock.Call
for i := 0; i < len(tc.mockHttpResps); i++ {
// Note: tc.mockHttpResps[i] is a *http.Response{}
fn := mockHttp.EXPECT().Post(gomock.Any(), gomock.Any(),gomock.Any()).Return(tc.mockHttpResps[i], tc.mockHttpErrs[i]).Times(1)
calls = append(calls, fn)
}
gomock.InOrder(
calls...
)
But it produces an error along these lines:
Unexpected call to *mock_rpc.MockHttp.Post because [function] has already been called the max number of times
If I try to set the calls to .AnyTimes()
then the error goes away but the first mocked function is still called multiple times. I then get other errors such as EOF
as the http.Response body is read twice, which is to be expected.
Note: I have tried to do exactly as in the linked post, but it leads to the same error.
答案1
得分: 1
如JonathanHall指出,没有必要模拟HTTP客户端。
这是修订后的可工作代码:
cnt := 0
// 模拟HTTP服务器
svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if tc.mockHttpErrs[cnt] != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintln(w, tc.mockHttpErrs[cnt].Error())
cnt++
return
}
fmt.Fprintf(w, tc.mockHttpResps[cnt])
cnt++
}))
defer svr.Close()
// 使用svr.URL和svr.Client()将其注入到需要的代码中
这样还可以更灵活地处理响应,而不依赖于gomock!
英文:
As JonathanHall pointed out there is no need to mock http clients.
This is the revised and working code:
cnt := 0
// mock http server
svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if tc.mockHttpErrs[cnt] != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintln(w, tc.mockHttpErrs[cnt].Error())
cnt++
return
}
fmt.Fprintf(w, tc.mockHttpResps[cnt])
cnt++
}))
defer svr.Close()
// use svr.URL and svr.Client() to inject into whatever code needs it
This also allows you to be more flexible regarding the responses without relying on gomock!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论