单元测试 Google 的 Go API 客户端
Unit Testing Google's Go API Client
我目前正在使用 Google 的 API go client 编写 Go 工作流。我是 Go 的新手,在对客户的服务进行单元测试时遇到了麻烦。这是在 Google 云项目中启用 API 的示例方法。
func (gcloudService *GCloudService) EnableApi(projectId string, apiId string) error {
service, err := servicemanagement.New(gcloudService.Client)
if err != nil {
return err
}
requestBody := &servicemanagement.EnableServiceRequest{
ConsumerId: consumerId(projectId),
}
_, err = service.Services.Enable(apiId, requestBody).Do()
if err != nil {
return err
}
return nil
}
GCloudService
是一个包含 Client 的简单结构。
type GCloudService struct {
Client *http.Client
}
这是我尝试测试这种方法。
var (
mux *http.ServeMux
client *http.Client
server *httptest.Server
)
func setup() {
// test server
mux = http.NewServeMux()
server = httptest.NewServer(mux)
// client configured to use test server
client = server.Client()
}
func teardown() {
server.Close()
}
func TestGCloudService_EnableApi(t *testing.T) {
setup()
defer teardown()
projectName := "test"
apiId := "api"
testGcloudService := &GCloudService{
Client: client,
}
path := fmt.Sprintf("/v1/services/{%s}:enable", apiId)
mux.HandleFunc(path,
func(w http.ResponseWriter, r *http.Request) {
// test things...
})
err := testGcloudService.EnableApi(projectName, apiId)
if err != nil {
t.Errorf("EnableApi returned error: %v", err)
}
}
然而,当我 运行 这个测试它仍然命中真正的 Google 端点而不是我的本地主机服务器,因为 EnableApi 使用配置了 API 的服务管理服务基地URL。我如何重构它以调用我的服务器而不是 API?我希望尽可能避免模拟整个服务管理服务。
使您的服务管理服务中的基础 url 可配置或可覆盖,如果它对您是隐藏的,那么您的代码不是为了测试方便而编写的,更改它,如果不可能,请向谁投诉负责。如果还是不行,深吸一口气,写个mock服务,一般不需要很复杂
我建议创建您自己的界面来包装 google api 客户端并提取您感兴趣的方法。
type MyWrapperClient interface {
SomeMethodWithCorrectReturnType()
}
type myWrapperClient struct {
*GCloudService.Client // or whatever
}
然后在目录中 运行:
mockery -name=MyWrapperClient
目录内(安装 mockery 后)
然后您可以访问您的模拟版本。然后在创建对象时用您的模拟替换您的客户端——因为接口和模拟具有相同的方法,它们可以互换。然后您可以测试是否使用特定参数调用方法 - 单独留下 google api 客户端代码。
更多关于 mockery 库的信息在这里:https://github.com/vektra/mockery
本文解决了您同样的问题,并且在解释如何模拟和抽象化您的顾虑方面绝对精彩。
https://medium.com/agrea-technogies/mocking-dependencies-in-go-bb9739fef008
我目前正在使用 Google 的 API go client 编写 Go 工作流。我是 Go 的新手,在对客户的服务进行单元测试时遇到了麻烦。这是在 Google 云项目中启用 API 的示例方法。
func (gcloudService *GCloudService) EnableApi(projectId string, apiId string) error {
service, err := servicemanagement.New(gcloudService.Client)
if err != nil {
return err
}
requestBody := &servicemanagement.EnableServiceRequest{
ConsumerId: consumerId(projectId),
}
_, err = service.Services.Enable(apiId, requestBody).Do()
if err != nil {
return err
}
return nil
}
GCloudService
是一个包含 Client 的简单结构。
type GCloudService struct {
Client *http.Client
}
这是我尝试测试这种方法。
var (
mux *http.ServeMux
client *http.Client
server *httptest.Server
)
func setup() {
// test server
mux = http.NewServeMux()
server = httptest.NewServer(mux)
// client configured to use test server
client = server.Client()
}
func teardown() {
server.Close()
}
func TestGCloudService_EnableApi(t *testing.T) {
setup()
defer teardown()
projectName := "test"
apiId := "api"
testGcloudService := &GCloudService{
Client: client,
}
path := fmt.Sprintf("/v1/services/{%s}:enable", apiId)
mux.HandleFunc(path,
func(w http.ResponseWriter, r *http.Request) {
// test things...
})
err := testGcloudService.EnableApi(projectName, apiId)
if err != nil {
t.Errorf("EnableApi returned error: %v", err)
}
}
然而,当我 运行 这个测试它仍然命中真正的 Google 端点而不是我的本地主机服务器,因为 EnableApi 使用配置了 API 的服务管理服务基地URL。我如何重构它以调用我的服务器而不是 API?我希望尽可能避免模拟整个服务管理服务。
使您的服务管理服务中的基础 url 可配置或可覆盖,如果它对您是隐藏的,那么您的代码不是为了测试方便而编写的,更改它,如果不可能,请向谁投诉负责。如果还是不行,深吸一口气,写个mock服务,一般不需要很复杂
我建议创建您自己的界面来包装 google api 客户端并提取您感兴趣的方法。
type MyWrapperClient interface {
SomeMethodWithCorrectReturnType()
}
type myWrapperClient struct {
*GCloudService.Client // or whatever
}
然后在目录中 运行:
mockery -name=MyWrapperClient
目录内(安装 mockery 后)
然后您可以访问您的模拟版本。然后在创建对象时用您的模拟替换您的客户端——因为接口和模拟具有相同的方法,它们可以互换。然后您可以测试是否使用特定参数调用方法 - 单独留下 google api 客户端代码。
更多关于 mockery 库的信息在这里:https://github.com/vektra/mockery
本文解决了您同样的问题,并且在解释如何模拟和抽象化您的顾虑方面绝对精彩。
https://medium.com/agrea-technogies/mocking-dependencies-in-go-bb9739fef008