-
Notifications
You must be signed in to change notification settings - Fork 2
testing
Testing webservices can be awkward. Mango tries to alleviate the problems through its test Browser
. To use the Browser
requires your Router to be created and initialized in a certain manner, but following the required structure will make your code easier to read and maintain.
func main() {
r := Router()
http.ListenAndServe(":8080", r)
}
func Router() *mango.Router {
r := mango.NewRouter()
// add any custom encoders
// add any custom param constraints
// add any pre/post hooks
// register the modules
router.RegisterModules([]mango.Registerer{
ordersHandler{},
accountsHandler{},
// ... other modules
})
return r
}
This structure enables an initialized Router
object to be acquired without calling the main
function, and thus not invoking the ListenAndServe()
method, and leaves the main
function clutter free. The Router()
method can now be called from a test to acquire a fully functioning Router, which can be tested using the Mango test Browser
. A Browser
should be created using the NewBrowser()
method, passing in the Router to test.
func TestGetHello(t *testing.T) {
want := "Hello world!"
// acquire the router
r := Router()
// use the router to create a test Browser
br := mango.NewBrowser(r)
// make calls (2nd parameter is headers - ignored in this test)
resp, _ := br.Get("/hello", nil)
got := resp.Body.String()
if got != want {
t.Errorf("Response body = %q, want %q", got, want)
}
}
The test Browser supports GET, POST, PUT, PATCH, HEAD, OPTIONS and DELETE methods. The browser methods Post
, Put
and Patch
accept an io.Reader
parameter for their request body; helper methods PostS
, PutS
and PatchS
, accept a body in string form.
func TestPostAndGetAccount(t *testing.T) {
r := Router()
br := mango.NewBrowser(r)
// Prepare and send the request
data:= `{"name":"mango","code":"MGO","category":"fruit"}`
hdrs := http.Header{}
hdrs.Set("Content-Type", "application/json")
resp, err := br.PostS("/accounts", data, hdrs)
// Check the error
if err != nil{
t.Errorf("Post failed, %q", err)
}
// Use the response (check headers, status code or body as required)
// Here we're using the Location header to create the subsequent GET
// request to retrieve the newly created Account.
// Get the response Location header from HeaderMap
location:= resp.HeaderMap.Get("Location")
resp, _ = br.Get(location, nil)
if resp.Code != http.StatusOK{
t.Errorf("Response status = %d, want 200 (OK)", resp.Code)
}
// Test the body
want := `{"name":"mango","code":"MGO","category":"fruit"}`
got := resp.Body.String()
if got != want {
t.Errorf("Response body = %q, want %q", got, want)
}
}