Testing an HTTP Server

A small example of testing an HTTP server endpoint


November 16, 2023

This is a small example of how to test an HTTP server endpoint. I’ve gotten in the bad habit of not writing tests for my Go code, and I need to brush up on how to write tests.

I’ll likely do a better version of this later that uses mocks, but for now, this will suffice.

The code below is split into 3 different files:


The contents of main.go are:

package main

func main() {
    s := NewServer()

This file really just bundles everything together and runs the application


The contents of server.go are:

package main

import (

//define a user type
type User struct {
    FirstName string
    Age       int

//define a server type
type Server struct {
    Srvr      *http.Server
    UserStore []*User

//create a new server with some dummy data included
func NewServer() *Server {
    return &Server{
        Srvr: &http.Server{
            Addr: ":8080",

        UserStore: []*User{
                FirstName: "John",
                Age:       29,
                FirstName: "Kendall",
                Age:       32,

//define a function to handle an endpoint requesting the user's age
func (s *Server) HandleGetUserAge(w http.ResponseWriter, r *http.Request) {
    q := r.URL.Query()
    firstName := q.Get("first_name")

    for _, user := range s.UserStore {
        if user.FirstName == firstName {
            fmt.Fprint(w, user.Age)

    fmt.Fprint(w, "user not found")

//run the server
func (s *Server) Run() {
    http.HandleFunc("/user", s.HandleGetUserAge)

This is all fairly self explanatory.


The contents of server_test.go, which is the thing I’m actually interested in here, are:

package main

//write a test for the handleGetUserAge endpoint

import (

func TestHandleGetUserAge(t *testing.T) {
    req, err := http.NewRequest("GET", "/user?first_name=John", nil) //create a request
    if err != nil {

    //note that creating a mock with a datastore is probably a better way to do this, but I defined the handler above as a method on the server, so I need another server here
    s := NewServer() //create a new server

    rr := httptest.NewRecorder()                    //create a response recorder, which is a tool that lets us test http responses
    handler := http.HandlerFunc(s.HandleGetUserAge) //create a handler function

    handler.ServeHTTP(rr, req) //call the handler function
    //note that since rr is a pointer, its data can be updated when this handler is called

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

    expected := "29"        //expected response. We know this is what shoul be returned since this is John's age in the dummy data we created
    got := rr.Body.String() //get the response body
    if got != expected {    //check the response body
        t.Errorf("handler returned unexpected body: got %v want %v",
            got, expected)

If we run the test, we’ll see that it passes.