doulu7921 2016-07-19 10:36
浏览 46
已采纳

使用Gorilla MUX的单元测试App Engine

I want to write tests for handlers in Google App Engine that use Gorilla mux to read variables from the request URL.

I understand from the documentation that you can create a fake context and request to use with testing.

I'm calling the handler directly in the test but the handler isn't seeing the path parameter as expected.

func TestRouter(t *testing.T) {
  inst, _ := aetest.NewInstance(nil) //ignoring error for brevity
  defer inst.Close()
  //tried adding this line because the test would not work with or without it
  httptest.NewServer(makeRouter())
  req, _ := inst.NewRequest("GET", "/user/john@example.com/id-123", nil)
  req.Header.Add("X-Requested-With", "XMLHttpRequest")
  resp := httptest.NewRecorder()
  restHandler(resp, req)
}

func restHandler(w http.ResponseWriter, r *http.Request) {
  ctx := appengine.NewContext(r)
  params := mux.Vars(r)
  email := params["email"]
  //`email` is always empty
}

The problem is that the handler always sees an empty "email" parameter because the path is not interpreted by Gorilla mux.

The router is as below:

func makeRouter() *mux.Router {
  r := mux.Router()
  rest := mux.NewRouter().Headers("Authorization", "").
    PathPrefix("/api").Subrouter()

  app := r.Headers("X-Requested-With", "XMLHttpRequest").Subrouter()
  app.HandleFunc("/user/{email}/{id}", restHandler).Methods(http.MethodGet)

  //using negroni for path prefix /api
  r.PathPrefx("/api").Handler(negroni.New(
    negroni.HandlerFunc(authCheck), //for access control
    negroni.Wrap(rest),
  ))
  return r
}

All my searches have not gotten anything specific to App Engine unit testing with Gorilla mux.

  • 写回答

1条回答 默认 最新

  • dqn8235 2016-10-14 19:41
    关注

    Since what you're testing is the handler, you could just get an instance of the router and call ServeHTTP on it. Here is how it should be based on your code.

    main.go

    func init() {
        r := makeRouter()
        http.Handle("/", r)
    }
    
    func makeRouter() *mux.Router {
        r := mux.NewRouter()
        app := r.Headers("X-Requested-With", "XMLHttpRequest").Subrouter()
        app.HandleFunc("/user/{email}/{id}", restHandler).Methods(http.MethodGet)
    
        return r
    }
    
    func restHandler(w http.ResponseWriter, r *http.Request) {
        params := mux.Vars(r)
        email := params["email"]
        fmt.Fprintf(w, email)
    }
    

    main_test.go

    func TestRouter(t *testing.T) {
        inst, _ := aetest.NewInstance(nil) //ignoring error for brevity
        defer inst.Close()
    
        req, _ := inst.NewRequest("GET", "/user/john@example.com/id-123", nil)
        req.Header.Add("X-Requested-With", "XMLHttpRequest")
        rec := httptest.NewRecorder()
    
        r := makeRouter()
        r.ServeHTTP(rec, req)
    
        if email := rec.Body.String(); email != "john@example.com" {
            t.Errorf("router failed, expected: %s, got: %s", "john@example.com", email)
        }
    }
    

    Notice I removed the rest routes since that's not part of your test, but the idea would be the same. Also didn't check for errors for simplicity.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作