在 golang 框架中编写依赖于外部服务的单元测试可以使用以下技巧:模拟外部服务行为:定义并模拟服务接口。使用模拟类型来创建测试并断言外部服务行为。实战案例:使用模拟类型测试依赖于 http 服务的外部服务。模拟服务端行为,并更新客户端指向模拟服务端。执行测试并断言结果。
如何在 GoLang 框架中编写依赖外部服务的单元测试
简介
编写依赖于外部服务的单元测试可能是一项艰巨的任务。在本指南中,我们将介绍在 GoLang 框架中编写此类测试的技巧。
立即学习“go语言免费学习笔记(深入)”;
模拟外部服务
一种常见的技术是模拟外部服务行为。我们使用 [mock](https://github.com/golang/mock) 包来定义接口和模拟类型。
package service // MyService 接口定义了外部服务行为 type MyService interface { GetData() (string, error) } // MyServiceMock 是 MyService 接口的模拟类型 type MyServiceMock struct { mock.Mock } // GetData 模拟外部服务的 GetData 方法 func (m *MyServiceMock) GetData() (string, error) { ret := m.Called() return ret.Get(0).(string), ret.Error(1) }
使用模拟类型
我们可以使用模拟类型来创建单元测试并断言外部服务的行为。
package service import ( "testing" "time" ) func TestService_GetData(t *testing.T) { // 创建模拟服务 mockService := &MyServiceMock{} // 设置 mock 行为 mockService.On("GetData").Return("sample data", nil).Once() service := NewService(mockService, time.Duration(0)) data, err := service.GetData() // 断言 if err != nil { t.Fatal(err) } if data != "sample data" { t.Fatalf("Expected 'sample data', got '%s'", data) } // 验证调用是否发生 if !mockService.AssertCalled(t, "GetData") { t.Error("GetData() was not called") } }
实战案例
以下是如何在集成测试中使用模拟类型测试依赖于外部服务的 HTTP 服务的示例:
package service_test import ( "context" "fmt" "io" "net/http" "net/http/httptest" "strings" "testing" "github.com/stretchr/testify/assert" ) func TestService_GetData(t *testing.T) { type args struct { ctx context.Context r *http.Request } tests := []struct { name string args args mockStatusCode int expectedBody string }{ { "Success", args{context.Background(), new(http.Request)}, http.StatusOK, "sample data", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // 模拟服务端行为 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != "GET" { t.Errorf("Unexpected HTTP method: %s", r.Method) } w.WriteHeader(tt.mockStatusCode) _, _ = io.WriteString(w, tt.expectedBody) })) defer server.Close() // 更新请求以指向模拟服务端 baseClient := Service.GetClient() t.Cleanup(func() { Service.SetClient(baseClient) }) Service.SetClient(http.Client{Transport: &http.Transport{ Base: &http.Transport{DisableCompression: true}, DialTLS: func(network, addr string) (net.Conn, error) { return net.Dial(network, strings.Replace(addr, "localhost", server.Listener.Addr().String(), 1)) }, }}) // 执行测试 result, err := Service.GetData(tt.args.ctx, tt.args.r) assert.Nil(t, err) assert.Equal(t, tt.expectedBody, result) }) } }
想要了解更多内容,请持续关注码农资源网,一起探索发现编程世界的无限可能!
本站部分资源来源于网络,仅限用于学习和研究目的,请勿用于其他用途。
如有侵权请发送邮件至1943759704@qq.com删除
码农资源网 » 如何在 golang 框架中编写依赖外部服务的单元测试?
本站部分资源来源于网络,仅限用于学习和研究目的,请勿用于其他用途。
如有侵权请发送邮件至1943759704@qq.com删除
码农资源网 » 如何在 golang 框架中编写依赖外部服务的单元测试?