如何使用不同的方法多次模拟调用 AWS 服务的 Golang 函数的单元测试?
Posted
技术标签:
【中文标题】如何使用不同的方法多次模拟调用 AWS 服务的 Golang 函数的单元测试?【英文标题】:How to mock unit tests for Golang function calling an AWS Service multiple times with different methods? 【发布时间】:2021-12-28 21:11:54 【问题描述】:我有以下对 AWS IAM 进行多次调用的函数。我能够在单个调用上运行单元测试。但是,当我在下面的一个上运行测试时,我会感到恐慌:“运行时错误,无效内存或 nil 指针取消引用”
func (iamDependency *iamService) CreateMyUser(userName string) (string, error)
//first IAM call
err:=iamDependency.GetUser(&iam.GetUserInputUserName: userName)
if err != nil
fmt.Println("Failed to get user, attempting to create")
//second IAM call
err:=iamDependency.CreateUser(&iam.CreateUserInputUserName: userName)
if err != nil
log.Fatalf("Failed to create user\n", err )
这是我的模拟和测试:
type mockSomeOutput
type mockedIamCall
iamiface.IAMAPI
Response mockSomeOutput
func TestCreateMyUser(t *testing.T)
t.Run("Successful user create", fun(t *testing.T)
mo:= mockOutput
m:= mockedIamCallResponse: mo
d:= iamService
iamInstance: m,
mockedUser:="TestUser"
_, err:= d.ResetCredentials(&mockedUser)
if err != nil
t.Fatal("Everything should be ok")
)
我想知道在 Golang 中为这种函数进行单元测试是否有任何技巧或指南。
感谢任何帮助。
【问题讨论】:
【参考方案1】:您可能想尝试使用:https://github.com/golang/mock
您可以为 iamiface.IAMAPI(从实际接口)创建模拟实现,然后期待函数调用并模拟响应。
使用mockgen
创建接口的模拟实现。
mockgen -source=path to IAM API interface
然后你可以在测试用例中期待这样的函数调用:
function TestExample(t *testing.T)
ctrl := gomock.NewController(t)
mockIAMAPI := mock_package.NewMockIAMAPI(ctrl)
mockIAMAPI.EXPECT().GetUser(expectedInput).Return(mockResponse).Times(1)
【讨论】:
您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。【参考方案2】:@Raymond 感谢您的回复,这很有见地。但是,我似乎找到了一个更简单的答案来解决我自己的问题。我创建了自己的界面
type UserCreator interface
GetUser(*iam.GetUserInput) (*iam.GetUserOutput, error)
CreateUser(*iam.CreateUserInput) (*iam.CreateUserInput, error)
func CreateMyUser(iamSvc UserCreator, userName string) (string, error)
//first IAM call
_, err:=iamSvc.GetUser(&iam.GetUserInputUserName: userName)
if err != nil
fmt.Println("Failed to get user, attempting to create")
//second IAM call
_, err:=iamSvc.CreateUser(&iam.CreateUserInputUserName: userName)
if err != nil
log.Fatalf("Failed to create user\n", err )
然后对于我的测试,我只是实现接口,覆盖这些方法,并传递一个模拟:
type mockUserCreator
Response string
func (m * mockUserCreator) GetUser(input *iam.GetUserInput)(*iam.GetUserOutput, error)
return &iam.GetUserOutput, nil
func (m * mockUserCreator) CreateUser(input *iam.CreateUserInput)(*iam.CreateUserOutput, error)
return &iam.CreateUserOutput, nil
func TestCreateMyUser(t *testing.T)
testcases:=[]struct
TestName string
TestName:"Some test"
for _, tt := range testcases
t.Run(tt.TestName, func(t *testing.T)
m := mockUserCreator
mockUser := "TestUser"
_, err:= CreateMyUser(&m, mockUser)
if err != nil
t.Error("TestCreateMyUser returned and error: %s", err)
【讨论】:
以上是关于如何使用不同的方法多次模拟调用 AWS 服务的 Golang 函数的单元测试?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Mockery 在模拟方法的第 N 次调用中引发异常