dongtan1009 2018-06-05 06:36
浏览 109

单元测试Google的Go API客户端

I am currently writing a workflow in Go that uses Google's API go client. I'm relatively new to Go and am having trouble unit testing the client's services. Here is an example method that enables an API in a Google Cloud Project.

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 is a simple struct that holds a Client.

type GCloudService struct {
   Client *http.Client

This is my attempt at testing this method.

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() {

func TestGCloudService_EnableApi(t *testing.T) {
  defer teardown()

  projectName := "test"
  apiId := "api"

  testGcloudService := &GCloudService{
     Client: client,

  path := fmt.Sprintf("/v1/services/{%s}:enable", apiId)

    func(w http.ResponseWriter, r *http.Request) {
        // test things...

  err := testGcloudService.EnableApi(projectName, apiId)
  if err != nil {
      t.Errorf("EnableApi returned error: %v", err)

However, when I run this test it still hits the real Google endpoint instead of my localhost server because EnableApi uses the servicemanagement service which is configured with the API's base URL. How do I refactor this to call my server instead of the API? I am hoping to avoid mocking the entire servicemanagement service if possible.

  • 写回答

2条回答 默认 最新

  • duan1226 2018-06-05 07:06

    Make the base url in your servicemanagement service configurable or overwritable, and if that is hidden for you, then your code is not written for test convenience, change that, and if not possible, complain to who is responsible. If that does not help, take a deep breath, and write a mock service, which is mostly not needed to be very complicated

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
  • douba9425 2019-03-12 02:50

    What I'd recommend is creating your own interface that wraps the google api client and extract the methods that you're interested in.

    type MyWrapperClient interface {
    type myWrapperClient struct {
      *GCloudService.Client // or whatever 

    In the directory I'd then run:

    mockery -name=MyWrapperClient inside the directory (after installing mockery)

    and then you can access your mocked version. Then on object creation substitute your mock in for your client - as the interface and the mock have the same methods they are interchangeable. Then you can test whether methods are called with specific params - leaving the google api client code alone.

    More information on the mockery library is here:

    This article solves your same problem and it's absolutely fantastic in explaining how to mock and abstract your concerns away.




  • ¥20 如何利用C语言实现用最小二乘法选配两个经验公式
  • ¥50 vue-codemirror如何对指定行 指定位置的 字符进行背景颜色或者字体颜色的修改?
  • ¥15 有人会思科模拟器嘛?
  • ¥30 遇到一个的问题,请教各位
  • ¥20 matlab报错,vflux计算潜流通量
  • ¥15 我该如何实现鼠标按下GUI按钮时就执行按钮里面的操作的方法
  • ¥15 关于#硬件工程#的问题:我这边有个锁相环电路没有效果
  • ¥15 20款 27寸imac苹果一体机装win10后,蓝牙耳机和音响放歌曲卡顿断断续续.
  • ¥15 VB.NET 父窗体调取子窗体报错
  • ¥15 python海龟作图如何改代码使其最后画出来的是一个镜像翻转的图形