Tests unitaires avec la AWS SDK pour Go v2 - AWS SDK pour Go v2

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Tests unitaires avec la AWS SDK pour Go v2

Lorsque vous utilisez le SDK dans votre application, vous devez simuler le SDK pour le test unitaire de votre application. Le fait de simuler le SDK permet à votre test de se concentrer sur ce que vous souhaitez tester, et non sur les composants internes du SDK.

Pour prendre en charge le simulacre, utilisez des interfaces Go plutôt que des types de clients de service, de paginateurs et de serveurs concrets, tels que. s3.Client Cela permet à votre application d'utiliser des modèles tels que l'injection de dépendances pour tester la logique de votre application.

Se moquer des opérations des clients

Dans cet exemple, S3GetObjectAPI il s'agit d'une interface qui définit l'ensemble des opérations d'API Amazon S3 requises par la GetObjectFromS3 fonction. S3GetObjectAPIest satisfait de la GetObjectméthode du client Amazon S3.

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) }

Pour tester la GetObjectFromS3 fonction, utilisez le mockGetObjectAPI pour satisfaire à la définition de S3GetObjectAPI l'interface. Utilisez ensuite le mockGetObjectAPI type pour simuler la sortie et les réponses d'erreur renvoyées par le client de service.

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) } }) } }

Paginateurs moqueurs

À l'instar des clients de service, les paginateurs peuvent être simulés en définissant une interface Go pour le paginateur. Cette interface serait utilisée par le code de votre application. Cela permet d'utiliser l'implémentation du SDK lorsque votre application est en cours d'exécution et d'utiliser une implémentation simulée à des fins de test.

Dans l'exemple suivant, ListObjectsV2Pager il s'agit d'une interface qui définit les comportements de l'Amazon S3 ListObjectsV2Paginator requis par fonction. 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 }

Pour testerCountObjects, créez le mockListObjectsV2Pager type correspondant à la définition de ListObjectsV2Pager l'interface. Utilisez-le ensuite mockListObjectsV2Pager pour reproduire le comportement de pagination des réponses de sortie et d'erreur du paginateur des opérations de service.

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) } }