天天看点

aws lambda 测试_在Go中对AWS Lambda进行单元测试

aws lambda 测试

当我开始在Go和AWS Lambda中工作时,我面临的困难之一是单元测试。 我对什么是单元测试有一个不错的想法,并且知道如何在Ruby中进行测试,但是在Go中,我不知道是什么原因,因为我是一个初学者。

学习围棋本身就是一个挑战。 主要是因为Go不是一种OOP语言。 我开始在Go上阅读文章,并在YouTube上观看了许多视频系列。 几天后,我逐渐好起来,并且能够理解事物。 但是我想学习如何进行单元测试,不幸的是,没有很多好的博客来说明如何使用Go进行AWS单元测试。 因此,此博客旨在解释如何使用Go正确地对AWS服务进行单元测试。

在博客中,我将演示如何对在Go中使用EMR服务的Lambda进行单元测试。 代码很简单,给出了集群ID,我必须获取集群状态。

永远记住,如果要在Go中进行单元测试,则必须使用接口,并尽可能避免使用具体的API或函数。 所以对于

aws-sdk-go

,我们有一些接口,例如

dynamodb

dynamodbiface

您可以看到aws-sdk-go来查看服务的iface名称是什么。 通常,其

service-nameiface.

现在开始编码

首先,我将创建将集群ID作为输入并将emr接口作为API的结构

// ClusterInput represent input which will be given to the lambda
type ClusterInput struct {
	ClusterID string `json:"clusterID"`
}

// awsService represents emr interface
type awsService struct {
	emr emriface.EMRAPI
}
           

接下来,我将创建一个函数,其功能是创建一个新的AWS会话并创建一个新的emr服务

// newAWSService returns a new instance of emr
func newAWSService () * awsService {
	awsConfig := &aws.Config{Region: aws.String( "us-west-2" )}
	sess, err := session.NewSession(awsConfig)
	if err != nil {
		log.Errorf( "error while creating AWS session - %s" , err.Error())
	}

	return &awsService{
		emr: emr.New(sess),
	}
}
           

现在,来了肉的部分。 我将进行输入验证,并准备输入

DescribeCluster

emr API方法。 休息就很简单。

// getClusterStatus returns current cluster status along with an error
func (svc *awsService) getClusterStatus (input ClusterInput) ( string , error) {
	clusterID := input.ClusterID
	if clusterID == "" {
		return "" , errors.New( "clusterID is empty" )
	}

	describeClusterInput := &emr.DescribeClusterInput{
		ClusterId: aws.String(clusterID),
	}

	clusterDetails, err := svc.emr.DescribeCluster(describeClusterInput)
	if err != nil {
		log.Errorf( "DescribeCluster error - %s" , err)
		return "" , err
	}

	if clusterDetails == nil {
		log.Errorf( "clusterID does not exist" )
		return "" , errors.New( "clusterID does not exist" )
	}

	clusterStatus := *clusterDetails.Cluster.Status.State

	return string (clusterStatus), nil
}
           

要了解的重点是我如何在

DescribeClusterInput

上使用

&emr

。 如果您想使用任何其他AWS服务,那么您应该做类似的事情。

现在开始测试

对于测试,我将使用Stretcher / Testify,因为它提供了模拟和断言功能。 尤其是模拟非常重要。 当您编写单元测试时,它不应该调用真实服务是至关重要的。 它应该始终调用模拟服务。

首先,我将创建模拟

emr

并创建

DescribeCluster

方法的模拟实现。 之后,我将创建

setup

方法

// mockEMR represents mock implementation of AWS EMR service
type mockEMR struct {
	emriface.EMRAPI
	mock.Mock
}

// DescribeCluster is a mocked method which return the cluster status
func (m *mockEMR) DescribeCluster (input *emr.DescribeClusterInput) (*emr.DescribeClusterOutput, error) {
	args := m.Called(input)
	return args.Get( 0 ).(*emr.DescribeClusterOutput), args.Error( 1 )
}

func setup () (*mockEMR, *awsService) {
	mockEMRClient := new (mockEMR)
	mockEMR := &awsService{
		emr: mockEMRClient,
	}

	return mockEMRClient, mockEMR
}
           

现在,该编写表驱动测试并调用原始函数了。 一旦调用了原始函数,我就可以断言预期结果是否与实际结果匹配。

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("DescribeCluster" , 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)
           

而已! 我希望阅读此博客后,您可以了解Go中的一点单元测试AWS Lambda。

检出aws-unit-test-golang以获取完整代码

翻译自: https://hackernoon.com/unit-test-aws-lambda-in-go-h85l3ymz

aws lambda 测试