Home > Net >  Golang unittest with *s3.S3 object
Golang unittest with *s3.S3 object

Time:03-15

How should I unittest following piece of code. I was trying to use coutnerfiter to fake input "*s3.S3" object, but it's not working for me. I am new to coutnerfiter and Go, Can someone please help me on that.

func (l *listContentImp) ListS3Content(client *s3.S3) (bool, error) {

  listObj := &s3.ListObjectsV2Input{
    Bucket: aws.String(l.bucket),
  }

  var err error
  l.lObj, err = client.ListObjectsV2(listObj)
  if err != nil {
    return false, err
  }

  return true, nil
}

CodePudding user response:

You shouldn't pass a reference to the s3.S3 struct. When using the AWS SDK for Go v1 you typically pass the services corresponding interface. For S3 this is s3iface.

The signature of your function would look like this:

func (l *listContentImp) ListS3Content(client s3iface.S3API) (bool, error)

Now every struct that you pass that implements at least one of the methods of s3iface.S3API will work.

At runtime you'll pass the proper service client, but in the unit tests you can just pass a mock:

type mock struct {
    s3iface.S3API

    output *s3.ListObjectsV2Output
    err     error
}

func (m mock) ListObjectsV2(*s3.ListObjectsV2Input) (*s3.ListObjectsV2Output, error) {
    return m.output, m.err
}

In your test you create the mock and pass it to your function:

func Test_ListObject(t *testing.T) {
    l := &listContentImp{...}
    m := mock{
        output: &s3.ListObjectsV2Output{...},
        err: nil
    }

    result, err := l.ListS3Content(m)
    
    [... add checks here...]
}
  • Related