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: "user@example.com"})
if err != nil {
t.Fatal("User should have been created")
}
})
}
- 1 回答
- 0 关注
- 100 浏览
添加回答
举报