doulan4939 2017-09-21 20:23
浏览 31
已采纳

如何使用httptest和处理程序在其定义中使用上下文来编写单元测试?

I've been trying for sometime to figure out how a write unit tests for handlers that use context as part of their definition.

Example

func Handler(ctx context.Context, w http.ResponseWriter, r *http.Request)

After some googling I came accross this article which made it seem as simple as

//copied right from the article

rr := httptest.NewRecorder()
// e.g. func GetUsersHandler(ctx context.Context, w http.ResponseWriter, r *http.Request)
handler := http.HandlerFunc(GetUsersHandler)

When trying to to implement the tests like this I was given the error

cannot convert Handler (type func("context".Context, http.ResponseWriter, *http.Request)) to type http.HandlerFunc

So I drove into the definition of HandleFunc and found

// The HandlerFunc type is an adapter to allow the use of
// ordinary functions as HTTP handlers. If f is a function
// with the appropriate signature, HandlerFunc(f) is a
// Handler that calls f.
type HandlerFunc func(ResponseWriter, *Request)

// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
    f(w, r)
}

So the error makes sense... but now I'm at a lose because I need to test this Handler and it doesn't seem like I can using httptest as the article suggested.

Is there anyway to test my handlers with the httptest package? If not how should I go about testing?

I'm using Go1.9

UPDATE

//Just so its clear this is what I'm currently trying to do

data := url.Values{}
data.Set("event_type", "click")
data.Set("id", "1")
data.Set("email", "")

req, err := http.NewRequest("PUT", "/", bytes.NewBufferString(data.Encode()))
Expect(err).To(BeNil())

rr := httptest.NewRecorder()
// this is the problem line. 
// The definition of Handler isn't (w ResponseWriter, r *Request)
// So I can't create a handler to serve my mock requests
handler := http.HandlerFunc(Handler)

handler.ServeHTTP(rr, req)
  • 写回答

1条回答 默认 最新

  • dsai1991 2017-09-21 20:29
    关注

    httptest includes everything you need to create a fake Request and ResponseWriter for testing purposes, you just need to create an appropriate fake Context (whatever that means in your situation) and then pass all 3 to your handler function and validate what it writes to the ResponseWriter:

    ctx := MakeMyContext()
    w := httptest.NewRecorder()
    r := httptest.NewRequest("GET", "/myroute", nil)
    // headers etc
    MyHandler(ctx,w,r)
    // Validate status, body, headers, whatever in r
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 unity第一人称射击小游戏,有demo,在原脚本的基础上进行修改以达到要求
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)