亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

AWS SDK Go Lambda 單元測試

AWS SDK Go Lambda 單元測試

Go
桃花長相依 2022-07-25 10:47:32
我第一次嘗試全神貫注地編寫一些單元測試,并且我正在 golang 中為使用 aws lambda 的輔助項目做這件事。下面是兩個文件。main.go接受一個包含電子郵件地址的事件,并在認知用戶池中創建用戶。main_test.go應該模擬中的createUser函數main.go,但是當我嘗試運行測試時出現錯誤。觀看此 youtube 視頻后,我剛剛將我的代碼從全局實例化客戶端切換為在 aws sdk 接口上使用指針接收器方法。錯誤Running tool: /usr/local/go/bin/go test -timeout 30s -run ^TestCreateUser$ github.com/sean/repo/src/create_user--- FAIL: TestCreateUser (0.00s)    --- FAIL: TestCreateUser/Successfully_create_user (0.00s)panic: runtime error: invalid memory address or nil pointer dereference [recovered]    panic: runtime error: invalid memory address or nil pointer dereference[signal SIGSEGV: segmentation violation code=0x1 addr=0x60 pc=0x137c2f2]goroutine 6 [running]:testing.tRunner.func1.1(0x13e00c0, 0x173fd70)    /usr/local/go/src/testing/testing.go:1072 +0x30dtesting.tRunner.func1(0xc000001b00)    /usr/local/go/src/testing/testing.go:1075 +0x41apanic(0x13e00c0, 0x173fd70)    /usr/local/go/src/runtime/panic.go:969 +0x1b9github.com/sean/repo/src/create_user.(*mockCreateUser).AdminCreateUser(0xc00000ee40, 0xc00006a200, 0xc00001e39d, 0x18, 0xc0000b24b0)    <autogenerated>:1 +0x32github.com/sean/repo/src/create_user.(*awsService).createUser(0xc000030738, 0x145bbca, 0x10, 0x18, 0x0)    /Users/sean/code/github/sean/repo/src/create_user/main.go:39 +0x2b7github.com/sean/repo/src/create_user.TestCreateUser.func1(0xc000001b00)    /Users/sean/code/github/sean/repo/src/create_user/main_test.go:30 +0x10ctesting.tRunner(0xc000001b00, 0x1476718)    /usr/local/go/src/testing/testing.go:1123 +0xefcreated by testing.(*T).Run    /usr/local/go/src/testing/testing.go:1168 +0x2b3FAIL    github.com/sean/repo/src/create_user    0.543sFAIL
查看完整描述

1 回答

?
白衣非少年

TA貢獻1155條經驗 獲得超0個贊

我認為這里的問題是,您想模擬該AdminCreateUser()方法,但實際上確實模擬了該CreateUser()方法。


因此,當您創建mockCreateUser結構的新實例時,“實現”cidpif.CognitoIdentityProviderAPI接口,然后調用它的AdminCreateUser()方法,它沒有實現并且失敗。


你的相關代碼main_test.go應該是這樣的:


type mockCreateUser struct {

    cidpif.CognitoIdentityProviderAPI

    Response cidp.AdminCreateUserOutput

}


func (d mockCreateUser) CreateUser(e createUserEvent) error {

    return nil

}

CreateUser()添加以下“虛擬”(并刪除該方法)就足夠了:


func (d mockCreateUser) AdminCreateUser(*cidp.AdminCreateUserInput) (*cidp.AdminCreateUserOutput, error) {

    return d.Response, nil

}

此外,我想提出一種稍微不同的方法來對您的 Lambda 進行單元測試。你的代碼在可測試性方面已經相當不錯了。但你可以做得更好。


我建議創建一個與您的awsService結構類似的“應用程序”,但不實現任何 AWS 接口。相反,它包含一個configuration結構。此配置包含您從環境中讀取的值(例如USER_POOL_ID, EMAIL)以及 AWS 服務的實例。


這個想法是您的所有方法和函數都使用此配置,允許您在單元測試期間使用模擬 AWS 服務并在運行時使用“適當的”服務實例。


以下是您的 Lambda 的簡化版本。顯然,命名等取決于您。還有很多錯誤處理缺失等。


我認為最大的優勢是,您可以config通過application. 如果您想在每個測試和不同的行為中使用不同的電子郵件等,您只需更改配置即可。


main.go


package main


import (

    "os"


    "github.com/aws/aws-lambda-go/events"

    "github.com/aws/aws-lambda-go/lambda"

    "github.com/aws/aws-sdk-go/aws"

    "github.com/aws/aws-sdk-go/aws/session"

    "github.com/aws/aws-sdk-go/service/cognitoidentityprovider"

    "github.com/aws/aws-sdk-go/service/cognitoidentityprovider/cognitoidentityprovideriface"

)


type createUserEvent struct {

    EmailAddress string `json:"email_address"`

}


type configuration struct {

    poolId string

    idp    cognitoidentityprovideriface.CognitoIdentityProviderAPI

}


type application struct {

    config configuration

}


func (app *application) createUser(event createUserEvent) error {

    input := &cognitoidentityprovider.AdminCreateUserInput{

        UserPoolId:             aws.String(app.config.poolId),

        Username:               aws.String(event.EmailAddress),

        DesiredDeliveryMediums: aws.StringSlice([]string{"EMAIL"}),

        ForceAliasCreation:     aws.Bool(true),

        UserAttributes: []*cognitoidentityprovider.AttributeType{

            {

                Name:  aws.String("email"),

                Value: aws.String(event.EmailAddress),

            },

        },

    }


    _, err := app.config.idp.AdminCreateUser(input)

    if err != nil {

        return err

    }


    return nil

}


func (app *application) handler(event createUserEvent) (events.APIGatewayProxyResponse, error) {

    err := app.createUser(event)

    if err != nil {

        return events.APIGatewayProxyResponse{}, err

    }


    return events.APIGatewayProxyResponse{}, nil

}


func main() {

    config := configuration{

        poolId: os.Getenv("USER_POOL_ID"),

        idp:    cognitoidentityprovider.New(session.Must(session.NewSession())),

    }


    app := application{config: config}


    lambda.Start(app.handler)

}

main_test.go


package main


import (

    "testing"


    "github.com/aws/aws-sdk-go/service/cognitoidentityprovider"

    "github.com/aws/aws-sdk-go/service/cognitoidentityprovider/cognitoidentityprovideriface"

)


type mockAdminCreateUser struct {

    cognitoidentityprovideriface.CognitoIdentityProviderAPI

    Response *cognitoidentityprovider.AdminCreateUserOutput

    Error    error

}


func (d mockAdminCreateUser) AdminCreateUser(*cognitoidentityprovider.AdminCreateUserInput) (*cognitoidentityprovider.AdminCreateUserOutput, error) {

    return d.Response, d.Error

}


func TestCreateUser(t *testing.T) {

    t.Run("Successfully create user", func(t *testing.T) {

        idpMock := mockAdminCreateUser{

            Response: &cognitoidentityprovider.AdminCreateUserOutput{},

            Error:    nil,

        }


        app := application{config: configuration{

            poolId: "test",

            idp:    idpMock,

        }}


        err := app.createUser(createUserEvent{EmailAddress: "[email protected]"})

        if err != nil {

            t.Fatal("User should have been created")

        }

    })

}


查看完整回答
反對 回復 2022-07-25
  • 1 回答
  • 0 關注
  • 124 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號