Skip to content

Instantly share code, notes, and snippets.

@cespare
Created February 20, 2013 03:05
Show Gist options
  • Save cespare/4992458 to your computer and use it in GitHub Desktop.
Save cespare/4992458 to your computer and use it in GitHub Desktop.
Example of testing Go HTTP servers using httptest.Server.
package main
import (
"log"
"myserver"
"net/http"
)
const addr = "localhost:12345"
func main() {
mux := http.NewServeMux()
handler := &myserver.MyHandler{}
mux.Handle("/favicon.ico", http.NotFoundHandler())
mux.Handle("/", handler)
log.Printf("Now listening on %s...\n", addr)
server := http.Server{Handler: mux, Addr: addr}
log.Fatal(server.ListenAndServe())
}
package myserver
import (
"fmt"
"net/http"
"sync"
)
type MyHandler struct {
sync.Mutex
count int
}
func (h *MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var count int
h.Lock()
h.count++
count = h.count
h.Unlock()
fmt.Fprintf(w, "Visitor count: %d.", count)
}
package myserver
import (
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"testing"
)
func TestMyHandler(t *testing.T) {
handler := &MyHandler{}
server := httptest.NewServer(handler)
defer server.Close()
for _, i := range []int{1, 2} {
resp, err := http.Get(server.URL)
if err != nil {
t.Fatal(err)
}
if resp.StatusCode != 200 {
t.Fatalf("Received non-200 response: %d\n", resp.StatusCode)
}
expected := fmt.Sprintf("Visitor count: %d.", i)
actual, err := ioutil.ReadAll(resp.Body)
if err != nil {
t.Fatal(err)
}
if expected != string(actual) {
t.Errorf("Expected the message '%s'\n", expected)
}
}
}
@IvRRimum
Copy link

IvRRimum commented Dec 14, 2016

Is there a way to test in this way, but without using type MyHandler struct? Seems a bit messy.

@IvRRimum
Copy link

IvRRimum commented Dec 14, 2016

Okey, i figured it out:

package main

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

type TestRegisterTokenHttpHandler struct{}

func (h *TestRegisterTokenHttpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	RegisterTokenHandle(w, r)
}

func TestRegisterTokenHandle(t *testing.T) {
	// Create server with register token handler
	h := &TestRegisterTokenHttpHandler{}
	server := httptest.NewServer(h)
	defer server.Close()

	// Make a test request
	resp, err := http.POST(server.URL)
	if err != nil {
		t.Fatal(err)
	}
	if resp.StatusCode != 200 {
		t.Fatalf("Received non-200 response: %d\n", resp.StatusCode)
	}
}

@ksrb
Copy link

ksrb commented Feb 14, 2017

For those stumbling onto this gist from google and slightly new to golang you can do something like this to get going:

cd $GOCODE
git clone [email protected]:4992458.git myserver
cd myserver
mv main.go ~/Desktop
cd ~/Desktop
go run main.go

You should be able to go to http://localhost:12345 and see Visitor count: 1.

To run the test assuming you've followed the above steps:

cd $GOCODE/myserver
go test

In your terminal you should see:

PASS
ok      myserver        0.010s

Basically the above just copies the code into you're $GOCODE and moves main.go out into you desktop. main.go is supposed to belong to a separate project but there isn't really a way to specify that in a gist.

@rredkovich
Copy link

👍

@lekhacman
Copy link

Do you know how to test the main.go? I'm trying to reach 100% code coverage here.

@distrill
Copy link

100% code coverage is not a useful thing to aspire to. You'll end up writing strange code for testing, rather than for solving the problem you're trying to solve.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment