This repository has been archived by the owner on Dec 27, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver_test.go
122 lines (96 loc) · 2.74 KB
/
server_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package main
import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"github.com/matryer/is"
)
// ---
// testing servers
func TestHandleAbout(t *testing.T) {
is := is.New(t)
srv := newServer() // create a new server inside each unit test
db, cleanup := connectTestDatabase()
defer cleanup()
srv.db = db // only set the dependency you need
r := httptest.NewRequest("GET", "/about", nil)
w := httptest.NewRecorder()
srv.ServeHTTP(w, r)
is.Equal(w.Result().StatusCode, http.StatusOK)
// ^ Mat has just w.StatusCode (typo or maybe older version?)
}
// ---
// testing inner types
func TestGreet(t *testing.T) {
is := is.New(t)
// handleGreet (in handlermethods.go) had an inner type request with a
// Name property, so we make an anonymous struct with a Name and encode
// as json
p := struct {
Name string `json:"name"`
}{
Name: "Mat Ryer",
}
var buf bytes.Buffer
err := json.NewEncoder(&buf).Encode(p)
is.NoErr(err) // json.NewEncoder
req := httptest.NewRequest(http.MethodPost, "/greet", &buf)
// ... more test code here
// ANCILLARY (to make compiler happy)
is.Equal(req.Method, http.MethodPost)
}
// ---
// integration vs. unit tests
func twoOrThreeWaysToTestServer(srv *server, w http.ResponseWriter, r *http.Request) {
// test the whole stack (integration test)
srv.ServeHTTP(w, r)
// test just this handler (unit test)
srv.handleGreet()(w, r)
// third way: e2e tests with http.Server below:
}
// ---
// e2e tests
// from https://pkg.go.dev/net/http/httptest?utm_source=gopls#Server
// An httptest.Server is an HTTP server listening on a system-chosen port on the
// local loopback interface, for use in end-to-end HTTP tests.
func TestTips(t *testing.T) {
h := newFakeRemoteService()
srv := httptest.NewServer(h)
defer srv.Close()
resp, err := http.Get(srv.URL + "/api/tips")
// ANCILLARY (to make compiler happy)
is := is.New(t)
is.NoErr(err)
is.Equal(200, resp.StatusCode)
}
// ---
// testing middleware
func TestAdminOnly(t *testing.T) {
var (
n int
w *responseWriter
r *http.Request
)
is := is.New(t)
h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
n++ // dummy handler increments n when called
})
srv := newServer()
h = srv.adminOnly(h)
// test: not admin
r = httptest.NewRequest(http.MethodGet, "/", nil)
r.Header.Set("Authorization", "Bearer no mate")
h(w, r)
is.Equal(n, 0) // should not get through
// test: yes, admin!
r = httptest.NewRequest(http.MethodGet, "/", nil)
r.Header.Set("Authorization", "Bearer VALID")
h(w, r)
is.Equal(n, 1) // should get through
}
// ---
// ANCILLARY STUBS (to make compiler happy)
func connectTestDatabase() (db *dbConn, cleanup func()) { return db, cleanup }
func newFakeRemoteService() (h http.HandlerFunc) { return h }