Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.
Pruebas unitarias con AWS SDK para Go v2
Cuando use el SDK en su aplicación, puede que quiera hacer una simulación de este para la prueba unitaria de la aplicación. Hacer una simulación del SDK permite que la prueba se centre en lo que quiere probar, no en los aspectos internos del SDK.
Para respaldar la simulación, use interfaces Go en lugar de tipos concretos de clientes de servicio, paginadores y esperadores, como s3.Client. Esto permite a la aplicación usar patrones como la inyección de dependencias para probar la lógica de la aplicación.
Simulación de operaciones de cliente
En este ejemplo, S3GetObjectAPI es una interfaz que define el conjunto de operaciones de la API de Amazon S3 que requiere la función GetObjectFromS3. S3GetObjectAPI se cumple con el método 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) }
Para probar la función GetObjectFromS3, utilice mockGetObjectAPI a fin de cumplir con la definición de la interfaz S3GetObjectAPI. A continuación, utilice el tipo mockGetObjectAPI para simular respuestas de salida y de error devueltas por el cliente de servicio.
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) } }) } }
Simulación de paginadores
Al igual que con los clientes de servicio, se puede hacer una simulación de los paginadores mediante la definición de una interfaz Go para el paginador. El código de su aplicación usaría esa interfaz. Esto permite utilizar la implementación del SDK durante la ejecución de la aplicación, así como una implementación simulada para la realización de pruebas.
En el siguiente ejemplo, ListObjectsV2Pager es una interfaz que define los comportamientos del objeto 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 }
Para probar CountObjects, cree el tipo mockListObjectsV2Pager que cumpla con la definición de la interfaz ListObjectsV2Pager. A continuación, use mockListObjectsV2Pager para replicar el comportamiento de paginación de las respuestas de salida y de error del paginador de operaciones de servicio.
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) } }