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")
}
})
}
- 1 回答
- 0 關注
- 124 瀏覽
添加回答
舉報