Unit-Tests mit dem AWS SDK für Go v2 - AWS SDK für Go v2

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Unit-Tests mit dem AWS SDK für Go v2

Wenn Sie das SDK in Ihrer Anwendung verwenden, sollten Sie das SDK für den Komponententest Ihrer Anwendung nachahmen. Wenn Sie das SDK nachahmen, kann sich Ihr Test auf das konzentrieren, was Sie testen möchten, und nicht auf die internen Komponenten des SDK.

Um Mocking zu unterstützen, verwenden Sie Go-Benutzeroberflächen anstelle von konkreten Service-Client-, Paginatoren- und Kellnertypen, wie z. s3.Client Auf diese Weise kann Ihre Anwendung Muster wie Dependency Injection verwenden, um Ihre Anwendungslogik zu testen.

Verspottung von Client-Vorgängen

In diesem Beispiel S3GetObjectAPI handelt es sich um eine Schnittstelle, die die für die GetObjectFromS3 Funktion erforderlichen Amazon S3 S3-API-Operationen definiert. S3GetObjectAPIist mit der GetObjectMethode des Amazon S3 S3-Clients zufrieden.

import "context" import "github.com/aws/aws-sdk-go-v2/service/s3" // ... type S3GetObjectAPI interface { GetObject(ctx context.Context, params *s3.GetObjectInput, optFns ...func(*s3.Options)) (*s3.GetObjectOutput, error) } func GetObjectFromS3(ctx context.Context, api S3GetObjectAPI, bucket, key string) ([]byte, error) { object, err := api.GetObject(ctx, &s3.GetObjectInput{ Bucket: &bucket, Key: &key, }) if err != nil { return nil, err } defer object.Body.Close() return ioutil.ReadAll(object.Body) }

Um die GetObjectFromS3 Funktion zu testen, verwenden Sie den, mockGetObjectAPI um die S3GetObjectAPI Schnittstellendefinition zu erfüllen. Verwenden Sie dann den mockGetObjectAPI Typ, um die Ausgabe und die vom Service-Client zurückgegebenen Fehlerantworten nachzuahmen.

import "testing" import "github.com/aws/aws-sdk-go-v2/service/s3" // ... type mockGetObjectAPI func(ctx context.Context, params *s3.GetObjectInput, optFns ...func(*s3.Options)) (*s3.GetObjectOutput, error) func (m mockGetObjectAPI) GetObject(ctx context.Context, params *s3.GetObjectInput, optFns ...func(*s3.Options)) (*s3.GetObjectOutput, error) { return m(ctx, params, optFns...) } func TestGetObjectFromS3(t *testing.T) { cases := []struct { client func(t *testing.T) S3GetObjectAPI bucket string key string expect []byte }{ { client: func(t *testing.T) S3GetObjectAPI { return mockGetObjectAPI(func(ctx context.Context, params *s3.GetObjectInput, optFns ...func(*s3.Options)) (*s3.GetObjectOutput, 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) } if params.Key == nil { t.Fatal("expect key to not be nil") } if e, a := "barKey", *params.Key; e != a { t.Errorf("expect %v, got %v", e, a) } return &s3.GetObjectOutput{ Body: ioutil.NopCloser(bytes.NewReader([]byte("this is the body foo bar baz"))), }, nil }) }, bucket: "amzn-s3-demo-bucket>", key: "barKey", expect: []byte("this is the body foo bar baz"), }, } for i, tt := range cases { t.Run(strconv.Itoa(i), func(t *testing.T) { ctx := context.TODO() content, err := GetObjectFromS3(ctx, tt.client(t), tt.bucket, tt.key) if err != nil { t.Fatalf("expect no error, got %v", err) } if e, a := tt.expect, content; bytes.Compare(e, a) != 0 { t.Errorf("expect %v, got %v", e, a) } }) } }

Spöttische Paginatoren

Ähnlich wie Service-Clients können Paginatoren verspottet werden, indem eine Go-Schnittstelle für den Paginator definiert wird. Diese Schnittstelle würde vom Code Ihrer Anwendung verwendet werden. Auf diese Weise kann die SDK-Implementierung verwendet werden, wenn Ihre Anwendung ausgeführt wird, und eine simulierte Implementierung zum Testen.

Im folgenden Beispiel ListObjectsV2Pager ist eine Schnittstelle, die das für die Funktion erforderliche Verhalten für den Amazon S3 ListObjectsV2Paginator definiert. CountObjects

import "context" import "github.com/aws/aws-sdk-go-v2/service/s3" // ... type ListObjectsV2Pager interface { HasMorePages() bool NextPage(context.Context, ...func(*s3.Options)) (*s3.ListObjectsV2Output, error) } func CountObjects(ctx context.Context, pager ListObjectsV2Pager) (count int, err error) { for pager.HasMorePages() { var output *s3.ListObjectsV2Output output, err = pager.NextPage(ctx) if err != nil { return count, err } count += int(output.KeyCount) } return count, nil }

Erstellen Sie zum Testen den mockListObjectsV2Pager TypCountObjects, der der Schnittstellendefinition entspricht. ListObjectsV2Pager Verwenden Sie dannmockListObjectsV2Pager, um das Paging-Verhalten der Ausgabe- und Fehlerantworten des Paginators für Dienstoperationen zu replizieren.

import "context" import "fmt" import "testing" import "github.com/aws/aws-sdk-go-v2/service/s3" // ... type mockListObjectsV2Pager struct { PageNum int Pages []*s3.ListObjectsV2Output } func (m *mockListObjectsV2Pager) HasMorePages() bool { return m.PageNum < len(m.Pages) } func (m *mockListObjectsV2Pager) NextPage(ctx context.Context, f ...func(*s3.Options)) (output *s3.ListObjectsV2Output, err error) { if m.PageNum >= len(m.Pages) { return nil, fmt.Errorf("no more pages") } output = m.Pages[m.PageNum] m.PageNum++ return output, nil } func TestCountObjects(t *testing.T) { pager := &mockListObjectsV2Pager{ Pages: []*s3.ListObjectsV2Output{ { KeyCount: 5, }, { KeyCount: 10, }, { KeyCount: 15, }, }, } objects, err := CountObjects(context.TODO(), pager) if err != nil { t.Fatalf("expect no error, got %v", err) } if expect, actual := 30, objects; expect != actual { t.Errorf("expect %v, got %v", expect, actual) } }