Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing 如何在golang对google云存储进行单元测试?_Unit Testing_Google App Engine_Go_Google Cloud Storage - Fatal编程技术网

Unit testing 如何在golang对google云存储进行单元测试?

Unit testing 如何在golang对google云存储进行单元测试?,unit-testing,google-app-engine,go,google-cloud-storage,Unit Testing,Google App Engine,Go,Google Cloud Storage,我正在用Go编写一个appengine应用程序,它使用 例如,我的“阅读”代码如下所示: client, err := storage.NewClient(ctx) if err != nil { return nil, err } defer func() { if err := client.Close(); err != nil { panic(err) } }() r, err := client.Bucket(BucketName).Object

我正在用Go编写一个appengine应用程序,它使用

例如,我的“阅读”代码如下所示:

client, err := storage.NewClient(ctx)
if err != nil {
    return nil, err
}
defer func() {
    if err := client.Close(); err != nil {
        panic(err)
    }
}()
r, err := client.Bucket(BucketName).Object(id).NewReader(ctx)
if err != nil {
    return nil, err
}
defer r.Close()
return ioutil.ReadAll(r)
。。。其中,
ctx
是来自appengine的上下文

当我在单元测试中运行此代码时(使用
aetest
),它实际上会向我的云存储发送请求;我想以密封方式运行它,类似于
aetest
如何允许假数据存储调用

(可能相关,但它涉及python,链接表示它是以特定于python的方式解决的)


如何做到这一点?

Python开发服务器上的云存储是通过Blobstore服务使用本地文件进行模拟的,这就是为什么使用Blobstore存根和测试床(也是特定于Python的)的解决方案起作用的原因。但是,对于移动云存储运行时,没有这样的本地模拟


正如Sachin所建议的,单元测试云存储的方法是使用模拟。这是在内部和其他运行时执行的方式,例如。

还建议的一种方法是允许您的GCS客户端在单元测试时将其下载程序换成存根。首先,定义一个与您使用Google云存储库的方式相匹配的接口,然后在单元测试中用伪数据重新实现它

大概是这样的:

type StorageClient interface {
  Bucket(string) Bucket  // ... and so on, matching the Google library
}

type Storage struct {
  client StorageClient
}

// New creates a new Storage client
// This is the function you use in your app
func New() Storage {
  return NewWithClient(&realGoogleClient{}) // provide real implementation here as argument
}

// NewWithClient creates a new Storage client with a custom implementation
// This is the function you use in your unit tests
func NewWithClient(client StorageClient) {
  return Storage{
    client: client,
  }
}

模拟整个第三方API可能需要大量的样板文件,因此,也许您可以通过使用或生成一些模拟来简化这一过程。

我建议您尽可能减少模拟,您可能需要使用一种密封的方法,使其与真实的API几乎相似。
我做过类似的事情

因为存储客户端正在发送HTTPS请求,所以我使用
httptest

func Test_StorageClient(t *testing.T) {
    tests := []struct {
        name        string
        mockHandler func() http.Handler
        wantErr     bool
    }{
        {
            name: "test1",
            mockHandler: func() http.Handler {
                return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                    w.Write([]byte("22\n96\n120\n"))
                    return
                })
            },
            wantErr: false,
        },
        {
            name: "test2 ",
            mockHandler: func() http.Handler {
                return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                    w.WriteHeader(http.StatusNotFound)
                    return
                })
            },
            wantErr: true,
        },
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            serv := httptest.NewTLSServer(tt.mockHandler())
            httpclient := http.Client{
                Transport: &http.Transport{
                    TLSClientConfig: &tls.Config{
                        InsecureSkipVerify: true,
                    },
                },
            }
            client, _ := storage.NewClient(context.Background(), option.WithEndpoint(serv.URL), option.WithoutAuthentication(), option.WithHTTPClient(&httpclient))
            got, err := readFileFromGCS(client)
            if (err != nil) != tt.wantErr {
                t.Errorf("error = %v, wantErr %v", err, tt.wantErr)
                return
            }
        })
    }
}

?@sachinnambiaranavatanon我在找一个假仓库;你是在建议我自己模拟它并实现一个假的吗?如果你最终调用了一个外部资源,你就不是在做单元测试。您有一个函数,可以获取文本并查找最常用的单词。此函数获取字节缓冲区并返回结果片段。在测试中,您获取一个字符串并将其转换为字节缓冲区,然后将其发送到函数;在生产中,您从GCS读取该文件并将其转换为字节缓冲区,然后发送到函数。