From 0eae5fc6b85636f3f9c63e42ec185baf4f3dedc1 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Thu, 2 Oct 2014 16:41:13 -0800 Subject: [PATCH] Added API tests. --- api/helpers_test.go | 25 ++++++++++++ api/server_for_test.go | 43 ++++++++++++++++++++ api/users.go | 2 +- api/users_test.go | 91 ++++++++++++++++++++++++++++++++++++++++++ test.sh | 2 +- 5 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 api/helpers_test.go create mode 100644 api/server_for_test.go create mode 100644 api/users_test.go diff --git a/api/helpers_test.go b/api/helpers_test.go new file mode 100644 index 0000000..89800d9 --- /dev/null +++ b/api/helpers_test.go @@ -0,0 +1,25 @@ +package api + +import ( + "encoding/json" + "fmt" + "reflect" +) + +// Helper function that normalizes structs for comparison with reflect.DeepEqual +func normalize(v interface{}) { + j, err := json.Marshal(v) + if err != nil { + panic(fmt.Sprintf("Could not normalize object %+v due to JSON marshalling error: %s", err)) + } + err = json.Unmarshal(j, v) + if err != nil { + panic(fmt.Sprintf("Could not normalize object %+v due to JSON un-marshalling error: %s", err)) + } +} + +func normalizeDeepEqual(u, v interface{}) bool { + normalize(u) + normalize(v) + return reflect.DeepEqual(u, v) +} diff --git a/api/server_for_test.go b/api/server_for_test.go new file mode 100644 index 0000000..ef07063 --- /dev/null +++ b/api/server_for_test.go @@ -0,0 +1,43 @@ +package api + +import ( + "bytes" + "io/ioutil" + "net/http" + "net/http/httptest" + + "github.com/thermokarst/bactdb/datastore" + "github.com/thermokarst/bactdb/models" +) + +func init() { + serveMux.Handle("/", http.StripPrefix("/api", Handler())) +} + +var ( + serveMux = http.NewServeMux() + httpClient = http.Client{Transport: (*muxTransport)(serveMux)} + apiClient = models.NewClient(&httpClient) +) + +func setup() { + store = datastore.NewMockDatastore() +} + +type muxTransport http.ServeMux + +// RoundTrip is for testing API requests. It intercepts all requests during testing +// to serve up a local/internal response. +func (t *muxTransport) RoundTrip(req *http.Request) (*http.Response, error) { + rw := httptest.NewRecorder() + rw.Body = new(bytes.Buffer) + (*http.ServeMux)(t).ServeHTTP(rw, req) + return &http.Response{ + StatusCode: rw.Code, + Status: http.StatusText(rw.Code), + Header: rw.HeaderMap, + Body: ioutil.NopCloser(rw.Body), + ContentLength: int64(rw.Body.Len()), + Request: req, + }, nil +} diff --git a/api/users.go b/api/users.go index 6b29c31..d783449 100644 --- a/api/users.go +++ b/api/users.go @@ -12,7 +12,7 @@ import ( ) func serveUser(w http.ResponseWriter, r *http.Request) error { - id, err := strconv.ParseInt(mux.Vars(r)["ID"], 10, 0) + id, err := strconv.ParseInt(mux.Vars(r)["Id"], 10, 0) if err != nil { return err } diff --git a/api/users_test.go b/api/users_test.go new file mode 100644 index 0000000..cba622d --- /dev/null +++ b/api/users_test.go @@ -0,0 +1,91 @@ +package api + +import ( + "testing" + + "github.com/thermokarst/bactdb/models" +) + +func TestUser_Get(t *testing.T) { + setup() + + wantUser := &models.User{Id: 1, UserName: "Test User"} + + calledGet := false + store.Users.(*models.MockUsersService).Get_ = func(id int64) (*models.User, error) { + if id != wantUser.Id { + t.Errorf("wanted request for user %d but got %d", wantUser.Id, id) + } + calledGet = true + return wantUser, nil + } + + gotUser, err := apiClient.Users.Get(wantUser.Id) + if err != nil { + t.Fatal(err) + } + + if !calledGet { + t.Error("!calledGet") + } + if !normalizeDeepEqual(wantUser, gotUser) { + t.Errorf("got user %+v but wanted user %+v", wantUser, gotUser) + } +} + +func TestUser_Create(t *testing.T) { + setup() + + wantUser := &models.User{Id: 1, UserName: "Test User"} + + calledPost := false + store.Users.(*models.MockUsersService).Create_ = func(user *models.User) (bool, error) { + if !normalizeDeepEqual(wantUser, user) { + t.Errorf("wanted request for user %d but got %d", wantUser, user) + } + calledPost = true + return true, nil + } + + success, err := apiClient.Users.Create(wantUser) + if err != nil { + t.Fatal(err) + } + + if !calledPost { + t.Error("!calledPost") + } + if !success { + t.Error("!success") + } +} + +func TestUser_List(t *testing.T) { + setup() + + wantUsers := []*models.User{{Id: 1, UserName: "Test User"}} + wantOpt := &models.UserListOptions{ListOptions: models.ListOptions{Page: 1, PerPage: 10}} + + calledList := false + store.Users.(*models.MockUsersService).List_ = func(opt *models.UserListOptions) ([]*models.User, error) { + if !normalizeDeepEqual(wantOpt, opt) { + t.Errorf("wanted options %d but got %d", wantOpt, opt) + } + calledList = true + return wantUsers, nil + } + + users, err := apiClient.Users.List(wantOpt) + if err != nil { + t.Fatal(err) + } + + if !calledList { + t.Error("!calledList") + } + for i, _ := range users { + if !normalizeDeepEqual(wantUsers[i], users[i]) { + t.Errorf("got users %+v but wanted users %+v", wantUsers, users) + } + } +} diff --git a/test.sh b/test.sh index 4a770db..9670bba 100755 --- a/test.sh +++ b/test.sh @@ -1,4 +1,4 @@ #!/usr/bin/env bash -PGTZ=UTC PGSSLMODE=disable go test ./... +PGTZ=UTC PGSSLMODE=disable go test -v ./...