为了账号安全,请及时绑定邮箱和手机立即绑定

如何在Golang测试中模拟一个进行外部调用的中间件?

如何在Golang测试中模拟一个进行外部调用的中间件?

Go
冉冉说 2022-11-23 19:23:26
有一个go-chi中间件正在进行外部调用以授权请求。我需要嘲笑它的作用。细节:我有这个测试:func Test_HTTP_UserSet_Create_InvalidAction(t *testing.T) {    requestBody :=        `{            "name": "test",            "action": "TEST"        }`    req, _ := http.NewRequest("POST", "/1234/users", bytes.NewBuffer([]byte(requestBody)))    recorder := setupInvalidActionRecorder(t, req)    if status := recorder.Code; status != http.StatusBadRequest {        t.Errorf("Status code expected to be %d but got %d", http.StatusBadRequest, status)        return    }}以上setupUnknownErrorRecorder是:func setupUnknownErrorRecorder(t *testing.T, request *http.Request) *httptest.ResponseRecorder {    recorder := httptest.NewRecorder()    c := resty.New()    resource := users.NewResource(        httpClient.NewHttpClient(log, &config.Server{}, &logger.LogRecord{}, c),    )    resource.Routes().ServeHTTP(recorder, request)    return recorder}我得到的结果是:=== RUN   Test_HTTP_UserSet_Create_InvalidAction    invalidAction_test.go:71: Status code expected to be 400 but got 401--- FAIL: Test_HTTP_UserSet_Create_InvalidAction (0.00s)c这个结果是预期的,因为服务器正在使用我传递给的客户端进行外部调用NewResource。有一个go-chi中间件正在使用此客户端进行外部调用。我的问题是:如何让这个 http 调用始终返回 200 而不是真正进行调用。又名如何嘲笑这个电话?编辑: 上面httpClient的接口是:type HttpClient struct {    logger          *logger.Logger    config          *config.Server    instrumentation *instrumentation    record          *logger.LogRecord    restyClient     *resty.Client}func NewHttpClient(    logger *logger.Logger,    config *config.Server,    record *logger.LogRecord,    restyClient *resty.Client,) HttpClient {    return HttpClient{        instrumentation: newInstrumentation(logger, record),        config:          config,        logger:          logger,        record:          record,        restyClient:     restyClient,    }}
查看完整描述

1 回答

?
凤凰求蛊

TA贡献1825条经验 获得超4个赞

可测试代码的一个非常基本的规则是,您不能只在其他服务中创建新服务。您需要注入它,并准备一个接口(如果返回的内容还没有接口的话)resty.New。这样你就可以在测试中注入你的模拟。


然后你可以使用例如https://pkg.go.dev/github.com/stretchr/testify/mock来生成模拟并说明你的模拟服务应该返回什么值。


评论后更新:


type HttpClient struct {

    logger          *logger.Logger

    config          *config.Server

    instrumentation *instrumentation

    record          *logger.LogRecord

    restyClient     *resty.Client // <- this is the thing you want to change from a pointer to resty.Client to an interface

}

检查restyClient您在代码中使用了哪些方法,并创建包含它们的新接口,例如:


type MyRestyClient interface {

   FirstUsedMethod(..)

   

   ...

}

并将 restyClient 声明交换为


type HttpClient struct {

    ...

    restyClient     MyRestyClient

之后,您可以使用我之前粘贴的链接中的模拟和命令为您生成模拟。


稍后,您只需在测试中设置模拟:


restyMock := new(RestyMock)

restyMock.On("MethodYouExpect").Return(returnValueOfYourChoice)


然后您将准备好的模拟注入到您的测试服务中。


查看完整回答
反对 回复 2022-11-23
  • 1 回答
  • 0 关注
  • 140 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号