首页 > 解决方案 > 使用 AWS 开发工具包集成测试 API 终端节点

问题描述

我正在尝试测试列出 AWS S3 存储桶中文件的 API 端点:

func listFiles(w http.ResponseWriter, _ *http.Request) {
    client := GetAWSClient()
    bucket := aws.String(BUCKETNAME)

    input := &s3.ListObjectsV2Input{
        Bucket: bucket,
    }

    resp, err := GetObjects(context.TODO(), client, input)
    if err != nil {
        ...
    }

    msg, _ := json.Marshal(resp.Contents)
    w.WriteHeader(200)
    w.Write(msg)
    return
}
...

func handleRequest() {
    myRouter := mux.NewRouter().StrictSlash(true)
    myRouter.HandleFunc("/listFiles", listFiles).Methods("GET")
    c := cors.Default()
    handler := c.Handler(myRouter)
    log.Fatal(http.ListenAndServe(":8080", handler))
}

我从 AWS SDK 文档中看到,要模拟 AWS 客户端功能,您可以使用它的接口,所以在我main_test.go创建了这些:

//Testing /listFiles endpoint

type mockListObjectsAPI func(ctx context.Context, params *s3.ListObjectsV2Input, optFns ...func(*s3.Options)) (*s3.ListObjectsV2Output, error)

func (m mockListObjectsAPI) ListObjectsV2(ctx context.Context, params *s3.ListObjectsV2Input, optFns ...func(*s3.Options)) (*s3.ListObjectsV2Output, error) {
    return m(ctx, params, optFns...)
}

func TestGetObjectFromS3(t *testing.T) {
    cases := []struct {
        client func(t *testing.T) S3ListObjectsAPI
        bucket string
        key    string
        expect []byte
    }{
        {
            client: func(t *testing.T) S3ListObjectsAPI {
                return mockListObjectsAPI(func(ctx context.Context, params *s3.ListObjectsV2Input, optFns ...func(*s3.Options)) (*s3.ListObjectsV2Output, error) {
                    t.Helper()
                    if params.Bucket == nil {
                        t.Fatal("expect bucket to not be nil")
                    }
                    if e, a := "fooBucket", *params.Bucket; e != a {
                        t.Errorf("expect %v, got %v", e, a)
                    }
                    return &s3.ListObjectsV2Output{
                        Name: aws.String("fooBucket"),
                    }, nil
                })
            },
            bucket: "fooBucket",
            key:    "barKey",
            expect: []byte("this is the body foo bar baz"),
        },
        //Add more test cases here if needed
    }

    for i, tt := range cases {
        t.Run(strconv.Itoa(i), func(t *testing.T) {
           //Here I should compare API returned value with expected in the test cases
        })
    }
}

我的问题是,我如何测试我的 API 从测试中调用它,但不调用 AWS,而是使用我模拟的值?

如果我使用 httptest 调用端点,它将调用调用 AWS 的真实端点。

标签: amazon-web-servicesgoamazon-s3mux

解决方案


推荐阅读