我正在尝试编写单元测试来模拟使用 GoMocks 发出的服务调用,这是一场真正的斗争。
我尝试简化代码的一种方法是创建一个私有方法,为所有模拟提供良好的响应,然后在需要模拟调用的不同响应的每个单独测试中(例如,测试模拟失败),我想用不同的响应覆盖该调用。
例如,设置模拟 fn(擦洗)
func setupMocks(s *SSAdapterV1Suite, userId string) {
s.mockDBDao.EXPECT().Mark(userId, gomock.Any()).
Return(nil)
s.mockDBDao.EXPECT().Get(userId).
Return(userData, nil)
s.mockDBDao.EXPECT().Delete(gomock.Any(), gomock.Any()).
Return(nil)
}
当我在"成功"场景中使用 setupMocks fn 时,它工作正常。
但是,如果我尝试在另一个单元测试中使用它,我想测试如何处理服务调用中的错误,gomocks 将使用 setupMocks fn 中的 mockResponse 设置,而不是我想覆盖的设置。
是否有我可以在 GoMocks 中执行的调用或操作,以用其他内容覆盖模拟EXPECT()
响应,而不是附加callstack
?
我在GoMocks代码中并没有真正看到任何提供此功能的方法。
我看到的一种方法是,您可以手动操作gomock控制器中的调用堆栈以尝试获得所需的内容。这可能比它的价值更复杂。幸运的是,我找到了一种更简单的解决方法,查看此线程中的评论:https://github.com/golang/mock/issues/137#issuecomment-440370200
你可以做的是在调用setupMocks()之前调用你的覆盖。通过以相反的顺序执行覆盖,您将获得所需的效果。
例如,
func (s *SSAdapterV1Suite) DeleteFails_Returns500() {
// Setup
req := makeRequest()
// Overrides need to go before setupMocks as a workaround for no mock override support.
// This may change in the future (c.f., https://github.com/golang/mock/issues/137#issuecomment-440370200)
expectedErrMsg := fmt.Errorf("Forced failure")
s.mockDBDao.EXPECT().
Delete(gomock.Any(), gomock.Any()).
Return(expectedErrMsg)
setupMocks(s, req.GetUserID())
// Run
resp, _ := s.server.RunTheThing(context.Background(), req)
// Assert
require.Equal(s.T(), int32(http.StatusInternalServerError), resp.GetStatus().GetCode())
require.Equal(s.T(), "", resp.GetStatus().GetError())
}
注意 创建模拟结构并将其连接到 ctrl 是在 SetupTests() fn 中完成的,并作为变量连接到 SSAdapterV1Suite。