Skip to content

Commit

Permalink
Public test API to set URL params (#322)
Browse files Browse the repository at this point in the history
* Add a function to set url params for test

* [docs] add justification for SetURLVars and description of alternative approach to setting url vars.
* rename SetURLParams to SetURLVars as this is more descriptive.
* rename testing to testing_helpers as this is more descriptive.

* [docs] add stipulation to SetURLVars that it should only be used for testing purposes
  • Loading branch information
grim-fendango authored and kisielk committed Dec 8, 2017
1 parent 7904d2e commit 5ab525f
Showing 1 changed file with 18 additions and 0 deletions.
18 changes: 18 additions & 0 deletions test_helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2012 The Gorilla Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package mux

import "net/http"

// SetURLVars sets the URL variables for the given request, to be accessed via
// mux.Vars for testing route behaviour.
//
// This API should only be used for testing purposes; it provides a way to
// inject variables into the request context. Alternatively, URL variables
// can be set by making a route that captures the required variables,
// starting a server and sending the request to that server.
func SetURLVars(r *http.Request, val map[string]string) *http.Request {
return setVars(r, val)
}

5 comments on commit 5ab525f

@picoeric
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import "github.com/gorilla/mux"
func TestCreatePerson(t *testing.T) {

personJson := `{"Role":1, "Firstname": "Testy", "Lastname": "Tester", "Address": {"City": "Seattle", "State": "WA", "Country": "USA"}}`

reader := strings.NewReader(personJson)

req, err := http.NewRequest("POST", "/people", reader)
if err != nil {
    t.Fatal(err)
}

req = mux.SetURLVars(req, map[string]string{"id":"3"})

rr := httptest.NewRecorder()
handler := http.HandlerFunc(CreatePersonHandler)
handler.ServeHTTP(rr, req)

if status := rr.Code; status != http.StatusOK {
    t.Errorf("handler returned wrong status code: got %v want %v",
        status, http.StatusOK)
}

if rr.Body.String() != personJson {
    t.Errorf("handler returned unexpected body: got %v want %v",
        rr.Body.String(), personJson)
}

}

go test
./main_test.go:84:11: undefined: mux.SetURLVars

..what am I missing?

@elithrar
Copy link
Contributor

@elithrar elithrar commented on 5ab525f Dec 11, 2017 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@picoeric
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did that: go get -u github.com/gorilla/mux
same error

@elithrar
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please open a new issue and fill out the issue template?

@picoeric
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Never mind. I reduced it down and now it works, so clearly a problem on my side. Thanks

//=================================================

//main.go

package main

import (
	"github.com/gorilla/mux"
	"encoding/json"
	"log"
	"net/http"
	"strconv"
	"os"
	"fmt"
)


func determineListenAddress() (string, error) {
  port := os.Getenv("PORT")
  if port == "" {
    return "", fmt.Errorf("$PORT not set")
  }
  return ":" + port, nil
}

type Person struct {
	ID        int   		`json:"id"`
	Firstname string   	`json:"firstname,omitempty"`
	Lastname  string   	`json:"lastname,omitempty"`
}

var people 		[]Person

func CreatePersonHandler(w http.ResponseWriter, r *http.Request) {

	var i int
	params := mux.Vars(r)
	var person Person

	if r.Body == nil {
		http.Error(w, "Body: No request body", 400)		//400: no body
		return
	}

	err := json.NewDecoder(r.Body).Decode(&person)
	if err != nil {
		http.Error(w, "Body: " + err.Error(), 400)		//400: poorly formed json in body
		return
	}
  defer r.Body.Close()

	i, err = strconv.Atoi(params["id"])
	if err != nil {
		http.Error(w, "ID: " + err.Error(), 400)			//400: poorly formed id
		return
	}

	for _, item := range people {
		if item.ID == i {
			http.Error(w, "ID: already exists", 400)		//400: id already exists
			return
		}
	}

	person.ID = i
	people = append(people, person)
	json.NewEncoder(w).Encode(person)								//200: person added, return it
}

func main() {
  addr, err := determineListenAddress()
  if err != nil {
    log.Fatal(err)
  }

	router := mux.NewRouter()

	router.HandleFunc("/people/{id}", CreatePersonHandler).Methods("POST")
		
  log.Printf("Listening on %s...\n", addr)
	log.Fatal(http.ListenAndServe(addr, router))
}

//main_test.go

package main

import (
		"github.com/gorilla/mux"
        "net/http"
		"net/http/httptest"
        "testing"
        "strings"
)

func TestCreatePerson(t *testing.T) {

    personJson := `{"Firstname": "Testy", "Lastname": "Tester"}`

    reader := strings.NewReader(personJson)

    req, err := http.NewRequest("POST", "/people", reader)
    if err != nil {
        t.Fatal(err)
    }
    
    req = mux.SetURLVars(req, map[string]string{"id":"3"})

    rr := httptest.NewRecorder()
    handler := http.HandlerFunc(CreatePersonHandler)

    handler.ServeHTTP(rr, req)

    if status := rr.Code; status != http.StatusOK {
        t.Errorf("handler returned wrong status code: got %v want %v",
            status, http.StatusOK)
    }

    expected := `{"id":3,"firstname":"Testy","lastname":"Tester"}`

    if strings.TrimSpace(rr.Body.String()) != strings.TrimSpace(expected) {

        t.Errorf("handler returned unexpected body: got %v want %v",
            rr.Body.String(), expected)
    }

}

Please sign in to comment.