模拟测试文件中定义的接口:接口“未定义”?

问题描述 投票:0回答:1

这是我尝试通过一个最小的示例进行重现的错误,但到目前为止仍未成功。 Go模块类似于以下内容:

.
├── go.mod
└── handler
    ├── handler.go
    ├── handler_test.go
    └── mock_handler.go

[handler.go为空(仅包含package handler),handler_test.go包含Handler接口定义(与Go的http.Handler相同)和占位符测试,

package handler

import (
    "net/http"
    "testing"
)

type Handler interface {
    ServeHTTP(http.ResponseWriter, *http.Request)
}

func TestMockHandler(t *testing.T) {
    mockHandler := MockHandler{}
    t.Log(mockHandler)
}

mock_handler.go包含实现MockHandler接口并使用Handler生成的moq结构:

moq

为了生成// Code generated by moq; DO NOT EDIT. // github.com/matryer/moq package handler import ( "net/http" "sync" ) var ( lockMockHandlerServeHTTP sync.RWMutex ) // Ensure, that MockHandler does implement Handler. // If this is not the case, regenerate this file with moq. var _ Handler = &MockHandler{} // MockHandler is a mock implementation of Handler. // // func TestSomethingThatUsesHandler(t *testing.T) { // // // make and configure a mocked Handler // mockedHandler := &MockHandler{ // 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 MockHandler 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 *MockHandler) ServeHTTP(in1 http.ResponseWriter, in2 *http.Request) { if mock.ServeHTTPFunc == nil { panic("MockHandler.ServeHTTPFunc: method is nil but Handler.ServeHTTP was just called") } callInfo := struct { In1 http.ResponseWriter In2 *http.Request }{ In1: in1, In2: in2, } lockMockHandlerServeHTTP.Lock() mock.calls.ServeHTTP = append(mock.calls.ServeHTTP, callInfo) lockMockHandlerServeHTTP.Unlock() mock.ServeHTTPFunc(in1, in2) } // ServeHTTPCalls gets all the calls that were made to ServeHTTP. // Check the length with: // len(mockedHandler.ServeHTTPCalls()) func (mock *MockHandler) ServeHTTPCalls() []struct { In1 http.ResponseWriter In2 *http.Request } { var calls []struct { In1 http.ResponseWriter In2 *http.Request } lockMockHandlerServeHTTP.RLock() calls = mock.calls.ServeHTTP lockMockHandlerServeHTTP.RUnlock() return calls } ,我最初在mock_handler.go中定义了Handler,然后在handler.go目录中运行了命令

handler

我随后将 moq -out mock_handler.go . Handler 接口定义移至Handler,因为它仅用于测试。

在此简化示例中,我能够在根目录下的程序包列表模式下运行handler_test.go

go test

我的“实际”模块具有类似的结构,类似于以下内容:

~/g/s/g/k/mockhandler> go test ./... -count=1
ok      github.com/kurtpeek/mockhandler/handler 0.448s

. ├── cmd │   └── root.go ├── images ├── main.go └── vpp ├── ensure_license_test.go └── mock_handler.go 接口在Handler中的定义与在简化模块中的ensure_license_test.go中完全相同; handler_test.go像这样开始:

ensure_license_test.go

package vpp import ( "encoding/json" "io/ioutil" "net/http" "net/http/httptest" "net/url" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) type Handler interface { ServeHTTP(http.ResponseWriter, *http.Request) } type MockTestServer struct { TestServer *httptest.Server MockHandler *MockHandler } 也与简​​化模块中的mock_handler.go完全相同(包名称除外)。

但是,当我在'实际'模块的根目录中运行mock_handler.go时,却收到go test ./...undefined错误:

Handler

奇怪的是,当我从~/g/s/g/f/vpp-client> go test ./... -count=1 # github.com/fleetsmith/vpp-client/vpp vpp/mock_handler.go:17:7: undefined: Handler ok github.com/fleetsmith/vpp-client/vpp 0.128s 包中运行此代码时,它通过了:

vpp

[在第一个示例中,从根目录以包列表模式运行> go test ./... -count=1 ok github.com/fleetsmith/vpp-client/vpp 0.601s 时,go test无法定义Handler的定义是什么原因?

go go-testing
1个回答
0
投票

原来是cmd程序包测试失败,因为它无法从Handler程序包中的测试文件导入vpp接口。因此,我将mock_handler.go的第17行更改为使用http.Handler而不是Handler

var _ http.Handler = &MockHandler{}

现在测试通过:

~/g/s/g/f/vpp-client> go test ./...
?       github.com/fleetsmith/vpp-client    [no test files]
?       github.com/fleetsmith/vpp-client/cmd    [no test files]
ok      github.com/fleetsmith/vpp-client/vpp    0.462s

我还能够从Handler中删除ensure_license_test.go接口的定义,因为我现在直接使用http标准库中的定义。

这种方法的缺点是它需要编辑由moq自动生成的代码,但是,我无法弄清楚如何运行moq来模拟Go的标准库中的接口,无论如何此界面不太可能更改。

© www.soinside.com 2019 - 2024. All rights reserved.