【问题标题】:Unit Testing Google's Go API Client对 Google 的 Go API 客户端进行单元测试
【发布时间】:2018-06-05 06:36:48
【问题描述】:

我目前正在使用 Google 的 API go client 在 Go 中编写工作流程。我对 Go 比较陌生,并且在对客户的服务进行单元测试时遇到了麻烦。以下是在 Google Cloud 项目中启用 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 是一个包含客户端的简单结构。

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?如果可能的话,我希望避免嘲笑整个服务管理服务。

【问题讨论】:

    标签: unit-testing go google-api client google-api-client


    【解决方案1】:

    使您的服务管理服务中的基本 url 可配置或可覆盖,如果这对您隐藏,那么您的代码不是为了方便测试而编写的,更改它,如果不可能,请向负责人投诉。如果这没有帮助,深呼吸,然后编写一个模拟服务,这通常不需要很复杂

    【讨论】:

      【解决方案2】:

      我的建议是创建您自己的界面来包装 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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-04
        相关资源
        最近更新 更多