When I started working in Go and AWS Lambda, one of the difficulties that I faced was unit testing. I had a decent idea about what is unit testing and knew how to do it in Ruby but in Go, I had no idea because I was a beginner. Learning Go was itself a challenge. Mainly because Go isn't a OOP language. I started reading articles on Go and watched numerous video series on YouTube. After a couple of days, I was getting better, and I was able to understand things. But I wanted to learn how to do unit testing and unfortunately, there aren’t many good blogs that explain how to do unit test AWS services using Go. So this blog is an effort to explain how to unit test properly AWS services using Go. In the blog, I will demonstrate how to unit test a lambda which uses EMR service in Go. The code is simple which is given a cluster id I have to get the cluster status. Always remember if you want to do unit testing in Go then you have to use interface and avoid using concrete API or function as far as possible. So for , we have interfaces for example for we have You can see to see what is the iface name of the service. Normally, its . aws-sdk-go dynamodb dynamodbiface aws-sdk-go service-nameiface. Now let’s start the coding First I will create structs which will have cluster id as an input and emr interface as an API ClusterInput { ClusterID } awsService { emr emriface.EMRAPI } // ClusterInput represent input which will be given to the lambda type struct string `json:"clusterID"` // awsService represents emr interface type struct Next, I will create a function whose job will be to create a new AWS session and create a new emr service { awsConfig := &aws.Config{Region: aws.String( )} sess, err := session.NewSession(awsConfig) err != { log.Errorf( , err.Error()) } &awsService{ emr: emr.New(sess), } } // newAWSService returns a new instance of emr * func newAWSService () awsService "us-west-2" if nil "error while creating AWS session - %s" return Now, comes the meaty part. I will do input validation and prepare input to the emr API method. Rest all is simple. DescribeCluster { clusterID := input.ClusterID clusterID == { , errors.New( ) } describeClusterInput := &emr.DescribeClusterInput{ ClusterId: aws.String(clusterID), } clusterDetails, err := svc.emr.DescribeCluster(describeClusterInput) err != { log.Errorf( , err) , err } clusterDetails == { log.Errorf( ) , errors.New( ) } clusterStatus := *clusterDetails.Cluster.Status.State (clusterStatus), } // getClusterStatus returns current cluster status along with an error func (svc *awsService) getClusterStatus (input ClusterInput) ( , error) string if "" return "" "clusterID is empty" if nil "DescribeCluster error - %s" return "" if nil "clusterID does not exist" return "" "clusterID does not exist" return string nil The important point to see is how I used on . If you want to use any other AWS service then you should be doing something similar. &emr DescribeClusterInput Let's start testing now For testing, I will be using because it provides and functionality. Especially mock is very important. When you write unit tests then its essential that it should not call the real service. It should always call mock service. stretchr/testify mock assert Here first I will create mock and create mock implementation of method. After that I will create method emr DescribeCluster setup mockEMR { emriface.EMRAPI mock.Mock } { args := m.Called(input) args.Get( ).(*emr.DescribeClusterOutput), args.Error( ) } { mockEMRClient := (mockEMR) mockEMR := &awsService{ emr: mockEMRClient, } mockEMRClient, mockEMR } // mockEMR represents mock implementation of AWS EMR service type struct // DescribeCluster is a mocked method which return the cluster status func (m *mockEMR) DescribeCluster (input *emr.DescribeClusterInput) (*emr.DescribeClusterOutput, error) return 0 1 func setup () (*mockEMR, *awsService) new return Now, it's time to write table driven tests and call original function. Once the original function is called then I can assert whether expected result match with the actual result or not. mockEMRClient, mockEMR := setup() mockDescribeClusterInput := &emr.DescribeClusterInput{ ClusterId: aws.String(testCase.clusterID), } mockDescribeClusterOutput := &emr.DescribeClusterOutput{ Cluster: &emr.Cluster{ Status: &emr.ClusterStatus{ State: aws.String(testCase.expectedClusterStatus), }, }, } mockEMRClient.On( , mockDescribeClusterInput).Return(mockDescribeClusterOutput, testCase.emrError) res, err := mockEMR.getClusterStatus(testCase.expectedInput) assert.Equal(t, testCase.expectedClusterStatus, res, testCase.message) assert.IsType(t, testCase.expectedError, err, testCase.message) "DescribeCluster" That's it! I hope after reading this blog you can understand little-bit of unit testing AWS lambdas in Go. Checkout for the full code aws-unit-test-golang