在golang中进行集成测试时如何模拟外部http请求api
Posted
技术标签:
【中文标题】在golang中进行集成测试时如何模拟外部http请求api【英文标题】:How to mock external http request api when integration test in golang 【发布时间】:2022-01-24 04:42:16 【问题描述】:我有一项服务可以获取数据库数据并从第三方 api 获取其他数据。
像这样:
type Service interface
GetDataFromDB(params apiParams, thirdClient ApiCient)
type Repository interface
GetDataFromDB(orm *gorm.DB)
type DataService struct
repo Repository
func (s *DataService) GetDataFromDB(params apiParams, thirdClient ApiClient) []interface
var result []interface
dataFromDb := s.repo.GetDataFromDB()
dataFromAPI := thirdClient.Do(url)
result = append(result, dataFromDb)
result = append(result, dataFromAPI)
return result
func getData(c *gin.Context)
//already implement interface
repo := NewRepository(orm)
srv := NewService(repo)
thirdPartyClient := NewApiClient()
params := ¶msId:1,Name:"hello world"
res := srv.GetDataFromDB(params, thirdPartyClient)
c.JSON(200,res)
func TestGetData(t *testing.T)
w := httptest.NewRecorder()
request := http.NewRequest(http.MethodGet, "/v1/get_data", nil)
route.ServeHTTP(w, request)
第三方api客户端会返回随机数据。 在这种情况下,我该怎么办? 如果我想模拟客户端以获得稳定的数据进行测试,如何在集成测试中伪造它?
【问题讨论】:
This article 有一些好的建议。 【参考方案1】:我假设“集成测试”意味着您将运行整个应用程序,然后测试正在运行的实例及其依赖项(在您的情况下是数据库和第三方服务)。我假设您不是指单元测试。
对于集成测试,您有几个选择。就我而言,通常我会进行集成测试,包括第三方客户端连接的任何内容(没有模拟),因为我想测试我的服务与第三方服务的集成。或者,如果这不可能,我可能会编写一个与第三方服务具有相同公共接口的简单存根应用程序,并在本地主机(或其他地方)上运行它,以便我的应用程序在测试期间连接到。
如果你不想或不能做这些并且想要在你的 Go 应用程序中存根外部依赖,你可以为第三方客户端编写一个接口,并在运行时提供接口的存根实现集成测试(在您的应用程序上使用一个标志来告诉它以“存根”模式或类似的方式运行)。
这是一个示例,说明这可能是什么样子。这是您发布的源代码文件 - 但使用的是获取第三方数据的接口:
type Service interface
GetDataFromDB(params apiParams, thirdClient ApiCient)
type Repository interface
GetDataFromDB(orm *gorm.DB)
type ThirdPartyDoer interface
Do(url string) interface
type DataService struct
repo Repository
thirdParty ThirdPartyDoer
func (s *DataService) GetDataFromDB(params apiParams, thirdClient ApiClient) []interface
var result []interface
dataFromDb := s.repo.GetDataFromDB()
dataFromAPI := s.thirdParty.Do(url)
result = append(result, dataFromDb)
result = append(result, dataFromAPI)
return result
然后您可以为ThirdPartyDoer
编写一个存根实现并在测试时使用它。在生产环境中运行时,您可以使用真正的第三方客户端作为ThirdPartyDoer
的实现:
type thirdPartyDoerStub struct
func (s *thirdPartyDoerStub) Do(url string) interface
return "some static test data"
// ...
// Test setup:
integrationTestDataService := &DataServicerepo: realRepository, thirdParty: &thirdPartyDoerStub
// Production setup:
integrationTestDataService := &DataServicerepo: realRepository, thirdParty: realThirdParty
在启动应用程序时,您需要有一个标志来在“测试设置”和“生产设置”之间进行选择。
【讨论】:
以上是关于在golang中进行集成测试时如何模拟外部http请求api的主要内容,如果未能解决你的问题,请参考以下文章
如何在 golang 中为我的测试用例正确创建模拟 http.request?
如何使用不同的方法多次模拟调用 AWS 服务的 Golang 函数的单元测试?