Go 模拟测试文件中定义的接口:“接口”;未定义的“;?
这是一个我试图用最少的例子重现的bug,但迄今为止没有成功。Go模块与以下类似:Go 模拟测试文件中定义的接口:“接口”;未定义的“;?,go,go-testing,Go,Go Testing,这是一个我试图用最少的例子重现的bug,但迄今为止没有成功。Go模块与以下类似: . ├── go.mod └── handler ├── handler.go ├── handler_test.go └── mock_handler.go . ├── cmd │ └── root.go ├── images ├── main.go └── vpp ├── ensure_license_test.go └── mock_handler.go 其中h
.
├── go.mod
└── handler
├── handler.go
├── handler_test.go
└── mock_handler.go
.
├── cmd
│ └── root.go
├── images
├── main.go
└── vpp
├── ensure_license_test.go
└── mock_handler.go
其中handler.go
为空(仅包含package handler
),handler\u 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
接口,并使用以下方法生成:
为了生成mock_handler.go
,我首先在handler.go
中定义了handler
,然后在handler
目录中运行命令
moq -out mock_handler.go . Handler
我随后将Handler
接口定义移动到Handler\u test.go
,因为它只用于测试
在这个简化的示例中,我能够在根目录下以包列表模式运行go test
:
~/g/s/g/k/mockhandler> go test ./... -count=1
ok github.com/kurtpeek/mockhandler/handler 0.448s
我的“实际”模块具有类似的结构,如下所示:
.
├── go.mod
└── handler
├── handler.go
├── handler_test.go
└── mock_handler.go
.
├── cmd
│ └── root.go
├── images
├── main.go
└── vpp
├── ensure_license_test.go
└── mock_handler.go
Handler
接口的定义方式与简化模块中的sure\u license\u test.go
中的Handler\u 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./…
时,我得到处理程序的未定义的错误:
~/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
var _ http.Handler = &MockHandler{}
奇怪的是,当我在vpp
包中运行这个时,它传递:
> go test ./... -count=1
ok github.com/fleetsmith/vpp-client/vpp 0.601s
在第一个示例中,当从根目录以包列表模式运行处理程序时,go test
无法定义处理程序的定义,这可能是什么原因?结果表明,测试失败的是cmd
包,因为它无法导入处理程序
来自vpp
包中测试文件的接口。因此,我将mock_handler.go
的第17行更改为使用http.handler
而不是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
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
我还可以从sure\u license\u test.go
中删除Handler
接口的定义,因为我现在直接使用http
标准库中的定义
这种方法的缺点是需要编辑由moq
自动生成的代码,我无法弄清楚如何在Go的标准库中运行moq
来模拟接口,在任何情况下,该接口都不太可能更改。没有在测试文件中声明的正常源文件引用标识符。如果需要在源文件中引用处理程序
,只需在源文件中声明即可。为什么?因为导入包时只导入源文件,不是测试文件,如果其中一个源文件引用了导入中未包含的测试文件中声明的标识符,则会出现未定义的编译器错误。这意味着当您执行go test./…
时,失败的不是vpp
包,而是其他包之一,导入vpp
,但失败的程序。