我有兴趣创建 httptest.Server
它只记录调用它的请求。为此,我想使用 github.com/matryer/moq
图书馆。
为 http.Handler
生成模拟,我将其定义复制到一个名为 client
的包中:
package client
import "net/http"
type Handler interface {
ServeHTTP(http.ResponseWriter, *http.Request)
}
然后我跑了
moq -out handler_mock.go . Handler
里面
client
目录,它产生了以下 handler_mock.go
:// Code generated by moq; DO NOT EDIT.
// github.com/matryer/moq
package client
import (
"net/http"
"sync"
)
var (
lockHandlerMockServeHTTP sync.RWMutex
)
// Ensure, that HandlerMock does implement Handler.
// If this is not the case, regenerate this file with moq.
var _ Handler = &HandlerMock{}
// HandlerMock is a mock implementation of Handler.
//
// func TestSomethingThatUsesHandler(t *testing.T) {
//
// // make and configure a mocked Handler
// mockedHandler := &HandlerMock{
// ServeHTTPFunc: func(in1 http.ResponseWriter, in2 *http.Request) {
// panic("mock out the ServeHTTP method")
// },
// }
//
// // use mockedHandler in code that requires Handler
// // and then make assertions.
//
// }
type HandlerMock struct {
// ServeHTTPFunc mocks the ServeHTTP method.
ServeHTTPFunc func(in1 http.ResponseWriter, in2 *http.Request)
// calls tracks calls to the methods.
calls struct {
// ServeHTTP holds details about calls to the ServeHTTP method.
ServeHTTP []struct {
// In1 is the in1 argument value.
In1 http.ResponseWriter
// In2 is the in2 argument value.
In2 *http.Request
}
}
}
// ServeHTTP calls ServeHTTPFunc.
func (mock *HandlerMock) ServeHTTP(in1 http.ResponseWriter, in2 *http.Request) {
if mock.ServeHTTPFunc == nil {
panic("HandlerMock.ServeHTTPFunc: method is nil but Handler.ServeHTTP was just called")
}
callInfo := struct {
In1 http.ResponseWriter
In2 *http.Request
}{
In1: in1,
In2: in2,
}
lockHandlerMockServeHTTP.Lock()
mock.calls.ServeHTTP = append(mock.calls.ServeHTTP, callInfo)
lockHandlerMockServeHTTP.Unlock()
mock.ServeHTTPFunc(in1, in2)
}
// ServeHTTPCalls gets all the calls that were made to ServeHTTP.
// Check the length with:
// len(mockedHandler.ServeHTTPCalls())
func (mock *HandlerMock) ServeHTTPCalls() []struct {
In1 http.ResponseWriter
In2 *http.Request
} {
var calls []struct {
In1 http.ResponseWriter
In2 *http.Request
}
lockHandlerMockServeHTTP.RLock()
calls = mock.calls.ServeHTTP
lockHandlerMockServeHTTP.RUnlock()
return calls
}
但是,如果我尝试运行以下
client_test.go
,package client
import (
"net/http"
"net/http/httptest"
"testing"
)
func TestHandlerMock(t *testing.T) {
handlerMock := HandlerMock{
ServeHTTPFunc: func(w http.ResponseWriter, r *http.Request) {},
}
ts := httptest.NewServer(handlerMock)
defer ts.Close()
}
我明白了
# github.com/kurtpeek/mock-handler/client [github.com/kurtpeek/mock-handler/client.test]
/Users/kurt/go/src/github.com/kurtpeek/mock-handler/client/client_test.go:14:26: cannot use handlerMock (type HandlerMock) as type http.Handler in argument to httptest.NewServer:
HandlerMock does not implement http.Handler (ServeHTTP method has pointer receiver)
FAIL github.com/kurtpeek/mock-handler/client [build failed]
Error: Tests failed.
确实,如果我查看
ServeHTTP
的实际定义(来自 https://github.com/golang/go/blob/c112289ee4141ebc31db50328c355b01278b987b/src/net/http/server.go#L2008-L2013 ),ServeHTTP()
没有指针接收器:// The HandlerFunc type is an adapter to allow the use of
// ordinary functions as HTTP handlers. If f is a function
// with the appropriate signature, HandlerFunc(f) is a
// Handler that calls f.
type HandlerFunc func(ResponseWriter, *Request)
// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
如何解决此问题以制作具有模拟处理程序函数的测试服务器?
最佳答案
错误消息是说您的 HandlerMock
没有实现接口(interface) http.Handler
.但是,*HandlerMock
确实实现了它:
func (mock *HandlerMock) ServeHTTP(in1 http.ResponseWriter, in2 *http.Request)
尝试更改语句
ts := httptest.NewServer(handlerMock)
至ts := httptest.NewServer(&handlerMock)
关于unit-testing - 如何使用 Go 的 moq 模拟 http.Handler?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59796530/