Introduction to HTTP Testing
HTTP Test in Golang has been provided with a special package for creating unit tests for Web features. All of this is in the net/http/httptest
package https://golang.org/pkg/net/http/httptest/. By using this package, we can unit test the web handler that we have created without having to run the web application so that we can immediately focus on the handler function that we want to test.
Methods in HTTP Test
httptest.NewRequest
is a function used to createhttp.Request
. We can determine the method, url, body that we will send as a unit test simulation. We can also add other additional information to the request we want to send, such as headers, cookies and so on.httptest.NewRecorder()
is the function used to createResponseRecorder
which is a help struct for recording the HTTP response from the results of the testing that we do.
How to implement HTTP Test
We are trying to create a handler that we can test, in the previous post we were able to create a HelloHandler
which in this session we will add a unit test for that handler. The way to do this is to create a file in the learning-golang-web
project and create the http_handler.go
file.
package main
import (
"fmt"
"net/http"
)
func HelloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello World")
}
If you use vscode then just open the file that we have created then hover our cursor over the function that we have created and right click select Go: Generate Unit Tests for function
. Then a file http_handler_test.go
will be created with contents like this.
package main
import (
"net/http"
"testing"
)
func TestHelloHandler(t *testing.T) {
type args struct {
w http.ResponseWriter
r *http.Request
}
tests := []struct {
name string
args args
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
HelloHandler(tt.args.w, tt.args.r)
})
}
}
Then we update the function and we will implement the httptest
package to look like this.
func TestHelloHandler(t *testing.T) {
tests := []struct {
name string
want string
}{
{
name: "mencetak Hello World",
want: "Hello World\n",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
request := httptest.NewRequest(http.MethodGet, "http://localhost/hello", nil)
recorder := httptest.NewRecorder()
HelloHandler(recorder, request)
response := recorder.Result()
body, _ := io.ReadAll(response.Body)
bodyString := string(body)
if !reflect.DeepEqual(bodyString, tt.want) {
t.Errorf("response = %v, want %v", bodyString, tt.want)
}
})
}
}
When we run the unit test with the command below
go test
then the result if it is appropriate will produce something like this
➜ learn-golang-web git:(main) ✗ go test
PASS
ok github.com/santekno/learn-golang-web 0.984s