Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mock example - no test files and working offline #116

Closed
kaihendry opened this issue Feb 6, 2018 · 12 comments · Fixed by #297
Closed

Mock example - no test files and working offline #116

kaihendry opened this issue Feb 6, 2018 · 12 comments · Fixed by #297
Labels
guidance Question that needs advice or information.

Comments

@kaihendry
Copy link

Hi, I'm struggling to understand the mocking example upon https://github.com/aws/aws-sdk-go-v2/tree/master/example/service/sqs/mockingClientsForTests

https://s.natalian.org/2018-02-06/mocking.mp4

Version of AWS SDK for Go?

39ee151

Version of Go (go version)?

go version go1.9.3 linux/amd64

What issue did you see?

?       command-line-arguments  [no test files]

Steps to reproduce

go test -tags example ifaceExample.go

from the README.md

Furthermore I tried to create a mocked example myself, but it still seems to dial out (it doesn't work whilst offline).

caused by: Get https://s3-ap-southeast-1.amazonaws.com/: dial tcp: lookup s3-ap-southeast-1.amazonaws.com: no such host

Is it because of the cfg?

Perhaps you can suggest how to handle the config here so all the functions can access it without any hoop jumping?

@xibz
Copy link
Contributor

xibz commented Feb 6, 2018

Hello @kaihendry, thank you for reaching out to us. You are using the s3.S3 client when calling lsBuckets. Which is why it is hitting the endpoint. You would just use the mockS3Client you created directly instead of the s3.S3 client. Think of the mock client as a substitute client for testing.

@kaihendry
Copy link
Author

Ok, so the existing structure I had where I was using a global cannot work here, right?

var (
       cfg, _ = external.LoadDefaultAWSConfig()
       client = s3.New(cfg)
)

Since IIUC, there is no way to override.

I think I got it working. https://s.natalian.org/2018-02-07/mocked.diff

Nonetheless what what the issue ? command-line-arguments [no test files] about with your test?

@gugahoi
Copy link

gugahoi commented Feb 7, 2018

You probably don't need to create your own type, can just accept the interface as a parameter in the method (untested):

// main.go
package main

import (
	"fmt"

	"github.com/aws/aws-sdk-go-v2/service/s3"
	"github.com/aws/aws-sdk-go-v2/service/s3iface"
)

func lsBuckets(client s3.s3iface) (results *s3.ListBucketsOutput, err error) {
	req := client.ListBucketsRequest(&s3.ListBucketsInput{})
	return req.Send()
}

func main() {
	cfg, _ = external.LoadDefaultAWSConfig()
	client = s3.New(cfg)

	res, err := lsBuckets(client)
	if err == nil {
		fmt.Println(res)
	}
}
// main_test.go
package main

import (
	"testing"

	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/service/s3"
	"github.com/aws/aws-sdk-go-v2/service/s3/s3iface"
)

type mockS3Client struct {
	s3iface.S3API
}

func (m mockS3Client) ListBucketsRequest(input *s3.ListBucketsInput) *s3.ListBucketsRequest {
	return &s3.ListBucketsRequest{
		Request: &aws.Request{},
		Input:   &s3.ListBucketsInput{},
	}
}

func TestListBuckets(t *testing.T) {
	mockClient = mockS3Client{}

	_, err := lsBuckets(mockClient)
	if err != nil {
		t.Fatal(err)
	}
}

@kaihendry
Copy link
Author

@gugahoi thanks for the alternative suggestion, though I don't like client as a parameter as it feels like some setup cruft I don't want to see an input to my function. Sorry, I'm probably being rather silly.

@jasdel jasdel added the guidance Question that needs advice or information. label Feb 7, 2018
@xibz
Copy link
Contributor

xibz commented Feb 7, 2018

@kaihendry, you could also specify the type in the client declaration.

package main

import "fmt"

type Fooer interface{
    Foo() string
}

type Bar struct{}
func (b *Bar) Foo() string {
    return "baz"
}

var client Fooer = &Bar{}

func main() {
	fmt.Println(client.Foo())
}

@kaihendry
Copy link
Author

Still don't quite understand how you would override client in main_test.go. Hopefully you'll add a simple example using an AWS API on https://github.com/aws/aws-sdk-go-v2/tree/master/example/service/sqs/mockingClientsForTests

@daviskoh
Copy link

daviskoh commented Mar 1, 2019

hmmm from that it seems like ListBucketsRequest would return nil and Send() in lsBuckets would fails w/ something like:

panic: interface conversion: interface {} is nil

@gugahoi
Copy link

gugahoi commented Mar 1, 2019

The point I wanted to make with that example is how you can mock a method in the struct and use the interface provided in the sdk. They have decent documentation on the interfaces themselves

// The best way to use this interface is so the SDK's service client's calls
// can be stubbed out for unit testing your code with the SDK without needing
// to inject custom request handlers into the SDK's request pipeline.
//
//    // myFunc uses an SDK service client to make a request to
//    // Amazon Simple Storage Service.
//    func myFunc(svc s3iface.S3API) bool {
//        // Make svc.AbortMultipartUpload request
//    }
//
//    func main() {
//        cfg, err := external.LoadDefaultAWSConfig()
//        if err != nil {
//            panic("failed to load config, " + err.Error())
//        }
//
//        svc := s3.New(cfg)
//
//        myFunc(svc)
//    }
//
// In your _test.go file:
//
//    // Define a mock struct to be used in your unit tests of myFunc.
//    type mockS3Client struct {
//        s3iface.S3API
//    }
//    func (m *mockS3Client) AbortMultipartUpload(input *s3.AbortMultipartUploadInput) (*s3.AbortMultipartUploadOutput, error) {
//        // mock response/functionality
//    }
//
//    func TestMyFunc(t *testing.T) {
//        // Setup Test
//        mockSvc := &mockS3Client{}
//
//        myfunc(mockSvc)
//
//        // Verify myFunc's functionality
//    }

@Skarlso
Copy link

Skarlso commented Mar 7, 2019

The problem is that the Send is on the Request object. You can't mock that. Basically if you have something after send and you need a return object on that one, you don't have anything at your disposal to do that. You will just return an empty request and you won't be able to mock / stub out the Send function which actually returns a response that you can test further.

Basically you can just test up until Send. After that you will need to get clever. Maybe stash it away in your own function that you would mock out. Have an object that can encapsulate this send.

@Skarlso
Copy link

Skarlso commented Mar 7, 2019

@kaihendry Please see my answer here that describes in detail with example on how to stub the Request in order to manipulate Send: #70 (comment)

@jasdel
Copy link
Contributor

jasdel commented Mar 18, 2019

Hi all, along with the discussion on how best the SDK can facilitate mocking of API operations, I'd like to also link PR #265 which adds Context to the API operation request's Send method. This change is being made so the SDK presents the Context as a first class concept. This pattern also improves the SDK's integration with other tracing libraries, (e.g X-Ray, or httptrace)

jasdel added a commit that referenced this issue Mar 18, 2019
…pkg (#278)

Updates the SDK's S3 Mock Paginator example to not use internal SDK packages and instead use the SDK's provided defaults package for default configuration.

Fix #116
@jasdel
Copy link
Contributor

jasdel commented Mar 18, 2019

Sorry closed this issue by mistake.

@jasdel jasdel reopened this Mar 18, 2019
jasdel added a commit to jasdel/aws-sdk-go-v2 that referenced this issue Apr 25, 2019
Services
---
* Synced the V2 SDK with latests AWS service API definitions.

SDK Breaking changes
---
* Update SDK API operation request send to required Context (aws#265)
  * Updates the SDK's API operation request Send method to require a context.Context value when called. This is done to encourage best applications to use Context for cancellation and request tracing.  Standardizing on this pattern will also help reduce code paths which accidentally do not have the Context causing the cancellation and tracing chain to be lost. Leading to difficult to trace down losses of cancellation and tracing within an application.
  * Fixes aws#264

SDK Enhancements
---
* Update README.md for getting SDK without Go Modules
  * Updates the README.md with instructions how to get the SDK without Go Modules enabled, or using the SDK within a GOPATH with Go 1.11, and Go 1.12.
* Refactor SDK's integration tests to be code generated (aws#283)
* `aws`: Add RequestThrottledException to set of throttled exceptions (aws#292)
* `private/model/api`: Backfill authtype, STS and Cognito Identity (aws#293)
  * Backfills the authtype=none modeled trait for STS and Cognito Identity services. This removes the in code customization for these two services' APIs that should not be signed.

SDK Bugs
---
* Fix HTTP endpoint credential provider test for unresolved hosts (aws#262)
  * Fixes the HTTP endpoint credential provider's tests to check for a host that resolves to no addresses.
* `example/service/s3/mockPaginator`: Update example to not use internal pkg (aws#278)
  * Updates the SDK's S3 Mock Paginator example to not use internal SDK packages and instead use the SDK's provided defaults package for default configuration.
  * Fixes aws#116
* Cleanup go mod unused dependencies (aws#284)
* `service/s3/s3manager`: Fix brittle Upload unit test (aws#288)
* `aws/ec2metadata`: Fix EC2 Metadata client panic with debug logging (aws#290)
  * Fixes a panic that could occur within the EC2 Metadata client when both AWS_EC2_METADATA_DISABLED env var is set and log level is LogDebugWithHTTPBody. The SDK's client response body debug functionality would panic because the Request.HTTPResponse value was not specified.
* `aws`: Fix RequestUserAgent test to be stable (aws#289)
* `private/protocol/rest`: Trim space in header key and value (aws#291)
  * Fixes a bug when using S3 metadata where metadata values with leading spaces would trigger request signature validation errors when the request is received by the service.
jasdel added a commit to jasdel/aws-sdk-go-v2 that referenced this issue Apr 25, 2019
Services
---
* Synced the V2 SDK with latests AWS service API definitions.

SDK Breaking changes
---
* Update SDK API operation request send to required Context (aws#265)
  * Updates the SDK's API operation request Send method to require a context.Context value when called. This is done to encourage best applications to use Context for cancellation and request tracing.  Standardizing on this pattern will also help reduce code paths which accidentally do not have the Context causing the cancellation and tracing chain to be lost. Leading to difficult to trace down losses of cancellation and tracing within an application.
  * Fixes aws#264

SDK Enhancements
---
* Update README.md for getting SDK without Go Modules
  * Updates the README.md with instructions how to get the SDK without Go Modules enabled, or using the SDK within a GOPATH with Go 1.11, and Go 1.12.
* Refactor SDK's integration tests to be code generated (aws#283)
* `aws`: Add RequestThrottledException to set of throttled exceptions (aws#292)
* `private/model/api`: Backfill authtype, STS and Cognito Identity (aws#293)
  * Backfills the authtype=none modeled trait for STS and Cognito Identity services. This removes the in code customization for these two services' APIs that should not be signed.

SDK Bugs
---
* Fix HTTP endpoint credential provider test for unresolved hosts (aws#262)
  * Fixes the HTTP endpoint credential provider's tests to check for a host that resolves to no addresses.
* `example/service/s3/mockPaginator`: Update example to not use internal pkg (aws#278)
  * Updates the SDK's S3 Mock Paginator example to not use internal SDK packages and instead use the SDK's provided defaults package for default configuration.
  * Fixes aws#116
* Cleanup go mod unused dependencies (aws#284)
* `service/s3/s3manager`: Fix brittle Upload unit test (aws#288)
* `aws/ec2metadata`: Fix EC2 Metadata client panic with debug logging (aws#290)
  * Fixes a panic that could occur within the EC2 Metadata client when both AWS_EC2_METADATA_DISABLED env var is set and log level is LogDebugWithHTTPBody. The SDK's client response body debug functionality would panic because the Request.HTTPResponse value was not specified.
* `aws`: Fix RequestUserAgent test to be stable (aws#289)
* `private/protocol/rest`: Trim space in header key and value (aws#291)
  * Fixes a bug when using S3 metadata where metadata values with leading spaces would trigger request signature validation errors when the request is received by the service.
jasdel added a commit to jasdel/aws-sdk-go-v2 that referenced this issue Apr 25, 2019
Services
---
* Synced the V2 SDK with latests AWS service API definitions.

SDK Breaking changes
---
* Update SDK API operation request send to required Context (aws#265)
  * Updates the SDK's API operation request Send method to require a context.Context value when called. This is done to encourage best applications to use Context for cancellation and request tracing.  Standardizing on this pattern will also help reduce code paths which accidentally do not have the Context causing the cancellation and tracing chain to be lost. Leading to difficult to trace down losses of cancellation and tracing within an application.
  * Fixes aws#264

SDK Enhancements
---
* Update README.md for getting SDK without Go Modules
  * Updates the README.md with instructions how to get the SDK without Go Modules enabled, or using the SDK within a GOPATH with Go 1.11, and Go 1.12.
* Refactor SDK's integration tests to be code generated (aws#283)
* `aws`: Add RequestThrottledException to set of throttled exceptions (aws#292)
* `private/model/api`: Backfill authtype, STS and Cognito Identity (aws#293)
  * Backfills the authtype=none modeled trait for STS and Cognito Identity services. This removes the in code customization for these two services' APIs that should not be signed.

SDK Bugs
---
* Fix HTTP endpoint credential provider test for unresolved hosts (aws#262)
  * Fixes the HTTP endpoint credential provider's tests to check for a host that resolves to no addresses.
* `example/service/s3/mockPaginator`: Update example to not use internal pkg (aws#278)
  * Updates the SDK's S3 Mock Paginator example to not use internal SDK packages and instead use the SDK's provided defaults package for default configuration.
  * Fixes aws#116
* Cleanup go mod unused dependencies (aws#284)
* `service/s3/s3manager`: Fix brittle Upload unit test (aws#288)
* `aws/ec2metadata`: Fix EC2 Metadata client panic with debug logging (aws#290)
  * Fixes a panic that could occur within the EC2 Metadata client when both AWS_EC2_METADATA_DISABLED env var is set and log level is LogDebugWithHTTPBody. The SDK's client response body debug functionality would panic because the Request.HTTPResponse value was not specified.
* `aws`: Fix RequestUserAgent test to be stable (aws#289)
* `private/protocol/rest`: Trim space in header key and value (aws#291)
  * Fixes a bug when using S3 metadata where metadata values with leading spaces would trigger request signature validation errors when the request is received by the service.
jasdel added a commit that referenced this issue Apr 25, 2019
Services
---
* Synced the V2 SDK with latest AWS service API definitions.

SDK Breaking changes
---
* Update SDK API operation request send to required Context (#265)
  * Updates the SDK's API operation request Send method to require a context.Context value when called. This is done to encourage best applications to use Context for cancellation and request tracing.  Standardizing on this pattern will also help reduce code paths which accidentally do not have the Context causing the cancellation and tracing chain to be lost. Leading to difficult to trace down losses of cancellation and tracing within an application.
  * Fixes #264

SDK Enhancements
---
* Update README.md for getting SDK without Go Modules
  * Updates the README.md with instructions how to get the SDK without Go Modules enabled, or using the SDK within a GOPATH with Go 1.11, and Go 1.12.
* Refactor SDK's integration tests to be code generated (#283)
* `aws`: Add RequestThrottledException to set of throttled exceptions (#292)
* `private/model/api`: Backfill authtype, STS and Cognito Identity (#293)
  * Backfills the authtype=none modeled trait for STS and Cognito Identity services. This removes the in code customization for these two services' APIs that should not be signed.

SDK Bugs
---
* Fix HTTP endpoint credential provider test for unresolved hosts (#262)
  * Fixes the HTTP endpoint credential provider's tests to check for a host that resolves to no addresses.
* `example/service/s3/mockPaginator`: Update example to not use internal pkg (#278)
  * Updates the SDK's S3 Mock Paginator example to not use internal SDK packages and instead use the SDK's provided defaults package for default configuration.
  * Fixes #116
* Cleanup go mod unused dependencies (#284)
* `service/s3/s3manager`: Fix brittle Upload unit test (#288)
* `aws/ec2metadata`: Fix EC2 Metadata client panic with debug logging (#290)
  * Fixes a panic that could occur within the EC2 Metadata client when both AWS_EC2_METADATA_DISABLED env var is set and log level is LogDebugWithHTTPBody. The SDK's client response body debug functionality would panic because the Request.HTTPResponse value was not specified.
* `aws`: Fix RequestUserAgent test to be stable (#289)
* `private/protocol/rest`: Trim space in header key and value (#291)
  * Fixes a bug when using S3 metadata where metadata values with leading spaces would trigger request signature validation errors when the request is received by the service.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
guidance Question that needs advice or information.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants