如何测试HTTP请求处理程序

I have a set of requests handlers like the one below:

func GetProductsHandler(w http.ResponseWriter, req *http.Request) {
    defer req.Body.Close()
    products := db.GetProducts()

    //    ...
    // return products as JSON array
}

How do I test them the right way? Should I send mock ResponseWriter and Request objects to the function and see the results?

Are there tools to mock request and response objects in Go to simplify the process without having to start server before testing?

Go provides a mock writer for use in testing handlers. The standard library documentation provides an example:

package main

import (
    "fmt"
    "net/http"
    "net/http/httptest"
)

func main() {
    handler := func(w http.ResponseWriter, r *http.Request) {
        http.Error(w, "something failed", http.StatusInternalServerError)
    }

    req := httptest.NewRequest("GET", "http://example.com/foo", nil)
    w := httptest.NewRecorder()
    handler(w, req)

    fmt.Printf("%d - %s", w.Code, w.Body.String())
}

I think having a global dependency (db) throws a wrench into clean unit testing. Using go your test could reassign a value, masking, the global value of db.

Another strategy (my preferred) is to package your handler in a struct, which has a db attribute..

type Handlers struct {
  db DB_INTERFACE
}

func (hs *Handlers) GetProductsHandler(w http.ResponseWriter, req *http.Request) {...}

This way your test can instantiate a Handlers with a stub db object which will allow you to create IO free unit tests.