Go Web API測試。
範例環境:
- Go 1.18
受測程式
POST|/employee
為受測的API,請求交由EmployeeHandler
處理,最終返回request body的JSON字串。
main.go
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
http.HandleFunc("/employee", EmployeeHandler)
http.ListenAndServe(":8080", nil)
}
func EmployeeHandler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodPost:
b, err := ioutil.ReadAll(r.Body)
if err != nil {
panic(err)
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
fmt.Fprint(w, string(b))
default:
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
}
測試程式
下面main_test.go
測試main.go
,TestEmployeeHandler_Post
直接測試EmployeeHandler
;TestEmployeeEndpoint_Post
則測試POST|/employee
API。不過注意這裡沒考慮到如果有service的mock需求。
main_test.go
package main
import (
"io"
"net/http"
"net/http/httptest"
"strings"
"testing"
)
func TestEmployeeHandler_Post(t *testing.T) {
// create testing request and response writer
w := httptest.NewRecorder()
body := "{\"id\":1,\"name\":\"John\",\"age\":33}"
r := httptest.NewRequest(http.MethodPost, "/employee", strings.NewReader(body))
// send testing request and response writer to target handler
EmployeeHandler(w, r)
if w.Result().StatusCode != http.StatusCreated {
t.Errorf("unexpected status code=%d", w.Result().StatusCode)
}
// read response body
b, err := io.ReadAll(w.Body)
if err != nil {
t.Errorf("read response body error, err=%v", err)
}
// verify result as expected
result := string(b)
if result != body {
t.Errorf("expected %v, but %v", body, result)
}
}
func TestEmployeeEndpoint_Post(t *testing.T) {
// create mock server with target endpoint handler
server := httptest.NewServer(http.HandlerFunc(EmployeeHandler))
defer server.Close()
// create http request with mock server's url
body := "{\"id\":1,\"name\":\"John\",\"age\":33}"
req, err := http.NewRequest(http.MethodPost, server.URL, strings.NewReader(body))
if err != nil {
t.Errorf("create request error, err=%v", err)
}
// send http request to mock server
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
t.Errorf("send request error, err=%v", err)
}
if resp.StatusCode != http.StatusCreated {
t.Errorf("unexpected status code=%d", resp.StatusCode)
}
// read response body
b, err := io.ReadAll(resp.Body)
if err != nil {
t.Errorf("read response body error, err=%v", err)
}
defer resp.Body.Close()
// verify result as expected
result := string(b)
if result != body {
t.Errorf("expected %v, but %v", body, result)
}
}
執行測試
在專案跟目錄以命令列輸入go test -v
結果如下。
$ go test -v
=== RUN TestEmployeeHandler_Post
--- PASS: TestEmployeeHandler_Post (0.00s)
=== RUN TestEmployeeEndpoint_Post
--- PASS: TestEmployeeEndpoint_Post (0.00s)
PASS
ok abc.com/demo 0.381s
沒有留言:
張貼留言