在请求处理程序中测试上下文中添加的值。

huangapple go评论82阅读模式
英文:

Testing the values added in context in a request handler

问题

我有一个处理程序函数,它在请求上下文中添加一些键/值,并希望对其进行单元测试。我的测试代码如下:

for _, tt := range tests {
	t.Run(tt.name, func(t *testing.T) {
		body := strings.NewReader(tt.payload)

		ctx := context.Background()
		ctx = context.WithValue(ctx, http.ContextUserKey, http.Account{ID: accID.String()})
		req, _ := nethttp.NewRequest("POST", "/api/groups/", body)
		req = req.WithContext(ctx)
		req.Header.Add("Content-Type", tt.contentType)

		rr := httptest.NewRecorder()

		router := mux.NewRouter()
		router.HandleFunc("/api/groups/", s.HandlePostGroups(kc, es, mySQL)).Methods("POST")
		router.ServeHTTP(rr, req)

		if rr.Code != tt.status {
			t.Errorf("wrong status code: got %v want %v", rr.Code, tt.status)
		}
		auditFields := req.Context().Value(http.AuditFields).(logrus.Fields)
        // 我想要断言的是 Audit fields,它们是在请求处理程序函数中添加的
    })
}
 

在处理程序函数内部,我像这样更新上下文:

func (s *IDMServer) HandlePostGroups(kc keycloak.API, es auth.KeyCreator, mySQL store.IDMRelationalStore) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        ctx := r.Context()
        // 在这里发生了很多事情,但是在代码的某个地方我这样做
        if err != nil {
			s.Log.WithField("error", err).Error("Unable to create key")
			auditFields["event.outcome"] = "failure"
			r = r.WithContext(context.WithValue(ctx, server.AuditFields, auditFields))
            return
        }
    }

}

所以我设置了一个描述事件的上下文。但是在我的测试中,我得到了一个错误:

panic: interface conversion: interface {} is nil, not logrus.Fields [recovered]
	panic: interface conversion: interface {} is nil, not logrus.Fields

因为该键不存在,返回的接口是nil。为什么上下文没有传播回测试函数?如何测试请求中的上下文?

英文:

I have a handler function that adds some key/values in the request context and wan to unittest it. My test is like this:

for _, tt := range tests {
	t.Run(tt.name, func(t *testing.T) {
		body := strings.NewReader(tt.payload)

		ctx := context.Background()
		ctx = context.WithValue(ctx, http.ContextUserKey, http.Account{ID: accID.String()})
		req, _ := nethttp.NewRequest("POST", "/api/groups/", body)
		req = req.WithContext(ctx)
		req.Header.Add("Content-Type", tt.contentType)

		rr := httptest.NewRecorder()

		router := mux.NewRouter()
		router.HandleFunc("/api/groups/", s.HandlePostGroups(kc, es, mySQL)).Methods("POST")
		router.ServeHTTP(rr, req)

		if rr.Code != tt.status {
			t.Errorf("wrong status code: got %v want %v", rr.Code, tt.status)
		}
		auditFields := req.Context().Value(http.AuditFields).(logrus.Fields)
        // Audit fields is what I want to assert. and are added in the request handler function
    })
}
 

Inside the handler function I update the context like this:

func (s *IDMServer) HandlePostGroups(kc keycloak.API, es auth.KeyCreator, mySQL store.IDMRelationalStore) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        ctx := r.Context()
        // Many things happening here but somewhere in code I do this
        if if err != nil {
			s.Log.WithField("error", err).Error("Unable to create key")
			auditFields["event.outcome"] = "failure"
			r = r.WithContext(context.WithValue(ctx, server.AuditFields, auditFields))
            return
        }
    }

}

So I set up a context to describe an event. But in my test I get a

panic: interface conversion: interface {} is nil, not logrus.Fields [recovered]
	panic: interface conversion: interface {} is nil, not logrus.Fields

because the key does not exist and the interface returned is nil. Why isn't the context propagating back to the test function. And how can you test your context in a request?

答案1

得分: 1

r = r.WithContext(...)更改了指针r。在这行代码之后,r指向一个新的请求。这个语句不会修改传入ServeHTTP的请求。

这回答了你的问题,为什么它不会向上游传播。

(我怀疑传播上下文更改到上游不是你应该尝试的事情。只需重新设计你的测试。)

英文:

r = r.WithContext(...) changes r which is a pointer. After that line r points to a new request. The incoming request to ServeHTTP is unmodified by this statement.

This answers your question why it's not propagated upstream.

(I doubt propagating context changes upstream is something you should try. Just redesign your test.)

huangapple
  • 本文由 发表于 2023年6月2日 14:43:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76387735.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定