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. S3GetObjectAPI
ist mit der GetObject
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 ListObjectsV2PaginatorCountObjects
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) } }