Sebelum kita melanjutkan ke modul web app testing menggunakan session. Pada modul ini kita akan sedikit membahas Test Environment.
Dapat kita lihat, fungsi test yang dibuat, menggunakan var app application dilakukan berulang kali pada fungsi dan file test yang berbeda.
Kita dapat menggunakan Test Environment untuk mendeklarasikannya secara global, sehingga dapat digunakan oleh masing-masing fungsi dan file test.
Untuk membuat test environment, buat file pada cmd/web/, dengan nama (wajib) setup_test.go
package main
import (
"os"
"testing"
)
var app application
// fungsi khusus, harus menggunakan nama fungsi seperti dibawah.
// fungsi ini akan selalu dijalankan diawal testing.
func TestMain(m *testing.M) {
os.Exit(m.Run())
}
Saat ini test environment yang kita buat hanya mendeklarasikan var app application saja.
Berikutnya, kita buang semua deklarasi var app application pada file test.
File handlers_test.go
package main
import (
"net/http"
"net/http/httptest"
"testing"
)
func Test_application_handlers(t *testing.T) {
var theTests = []struct {
name string
url string
expectedStatusCode int
}{
{"home", "/", http.StatusOK},
{"404", "/qwerty", http.StatusNotFound},
}
//menggunakan environment variable
//var app application
routes := app.routes()
//create a test server
ts := httptest.NewTLSServer(routes)
defer ts.Close()
templatePath = "./../../templates/"
//testing
for _, e := range theTests {
resp, err := ts.Client().Get(ts.URL + e.url)
if err != nil {
t.Log(err)
t.Fatal(err)
}
if resp.StatusCode != e.expectedStatusCode {
t.Errorf("for %s: expected status %d, but got %d", e.name, e.expectedStatusCode, resp.StatusCode)
}
}
}
File midlleware_test.go
package main
import (
"context"
"net/http"
"net/http/httptest"
"strings"
"testing"
)
func Test_application_addIPToContext(t *testing.T) {
tests := []struct {
headerName string
heaaderValue string
addr string
emptyaddr bool
}{
{"", "", "", false},
{"", "", "", true},
{"X-Forwarded-For", "192.163.1.3", "", false},
{"", "", "hello:skillplus", false},
}
//menggunakan environment variable
//var app application
//create dummy handler
nextHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
//check whether value exists in the context
val := r.Context().Value(contextUserKey)
if val == nil {
t.Error(contextUserKey, "not present")
}
//make sure get the string back
ip, ok := val.(string)
if !ok {
t.Error("not string")
}
t.Log(ip)
})
for _, e := range tests {
//create handler for test
handlerToTest := app.addIPToContext(nextHandler)
req := httptest.NewRequest("GET", "http://testing/", nil)
if e.emptyaddr {
req.RemoteAddr = ""
}
if len(e.headerName) > 0 {
req.Header.Add(e.headerName, e.heaaderValue)
}
if len(e.addr) > 0 {
req.RemoteAddr = e.addr
}
handlerToTest.ServeHTTP(httptest.NewRecorder(), req)
}
}
func Test_application_ipFromContext(t *testing.T) {
//menggunakan environment variable
//var app application
//get a context
ctx := context.Background()
//put somtehing in the context
ctx = context.WithValue(ctx, contextUserKey, "random")
//call the function
ip := app.ipFromContext(ctx)
//perform test
if !strings.EqualFold("random", ip) {
t.Error("wrong value returned from context")
}
}
File routes_test.go
package main
import (
"net/http"
"strings"
"testing"
"github.com/go-chi/chi/v5"
)
func Test_application_routes(t *testing.T) {
var registered = []struct {
route string
method string
}{
{"/", "GET"},
{"/login", "POST"},
{"/static/*", "GET"},
}
//menggunakan environment variable
//var app application
mux := app.routes()
chiRoutes := mux.(chi.Routes)
for _, route := range registered {
//check if the route exists
if !routeExists(route.route, route.method, chiRoutes) {
t.Errorf("route %s is not registered", route.route)
}
}
}
func routeExists(testRoute, testMethod string, chiRoutes chi.Routes) bool {
found := false
_ = chi.Walk(chiRoutes, func(method string, route string, handler http.Handler, middleware ...func(http.Handler) http.Handler) error {
if strings.EqualFold(method, testMethod) && strings.EqualFold(route, testRoute) {
found = true
}
return nil
})
return found
}
Silakan jalankan test untuk memastikan modifikasi diatas tidak menyebabkan error.
$ go test ./...
ok webapp/cmd/web 0.307s