Can you mock the page values in an AWS API Paginator/paginated/Pages call?

Viewed 136

Is there a way to return test page values returned from the AWS API paginators to test the code below? If not, I suppose it's better to split the tag checking into a function that can be tested in isolation?

Note: This is just an example, I realize there are input Filters on the I can apply to the API call to achieve the same thing demonstrated here.

package main

import (
    "fmt"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/ec2"
    "github.com/aws/aws-sdk-go/service/ec2/ec2iface"
)

type handler struct {
    EC2 ec2iface.EC2API
}

func main() {
    sess := session.New()
    client := ec2.New(sess)

    h := &handler{EC2: client}
    tagged, err := h.findTagged()
    if err != nil {
        panic(err)
    }
    fmt.Println(tagged)
}

func (h *handler) findTagged() ([]string, error) {
    defaults := []string{}

    input := &ec2.DescribeVpcsInput{}
    err := h.EC2.DescribeVpcsPages(input, func(page *ec2.DescribeVpcsOutput, lastPage bool) bool {
        for _, p := range page.Vpcs {
            for _, t := range p.Tags {
                if aws.StringValue(t.Key) == "test" {
                    defaults = append(defaults, aws.StringValue(p.VpcId))
                }
            }
        }
        return false
    })

    return defaults, err

}
1 Answers

This is described on the official documentation (Unit Testing with the AWS SDK for Go V2 - How to mock the AWS SDK for Go V2 when unit testing your application

Extract from the page:

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