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
|
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"testing"
"github.com/DATA-DOG/go-sqlmock"
)
func (a *api) assertJSON(actual []byte, data interface{}, t *testing.T) {
expected, err := json.Marshal(data)
if err != nil {
t.Fatalf("an error '%s' was not expected when marshaling expected json data", err)
}
if bytes.Compare(expected, actual) != 0 {
t.Errorf("the expected json: %s is different from actual %s", expected, actual)
}
}
func TestShouldGetPosts(t *testing.T) {
db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
defer db.Close()
// create app with mocked db, request and response to test
app := &api{db}
req, err := http.NewRequest("GET", "http://localhost/posts", nil)
if err != nil {
t.Fatalf("an error '%s' was not expected while creating request", err)
}
w := httptest.NewRecorder()
// before we actually execute our api function, we need to expect required DB actions
rows := sqlmock.NewRows([]string{"id", "title", "body"}).
AddRow(1, "post 1", "hello").
AddRow(2, "post 2", "world")
mock.ExpectQuery("^SELECT (.+) FROM posts$").WillReturnRows(rows)
// now we execute our request
app.posts(w, req)
if w.Code != 200 {
t.Fatalf("expected status code to be 200, but got: %d", w.Code)
}
data := struct {
Posts []*post
}{Posts: []*post{
{ID: 1, Title: "post 1", Body: "hello"},
{ID: 2, Title: "post 2", Body: "world"},
}}
app.assertJSON(w.Body.Bytes(), data, t)
// we make sure that all expectations were met
if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("there were unfulfilled expectations: %s", err)
}
}
func TestShouldRespondWithErrorOnFailure(t *testing.T) {
db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
defer db.Close()
// create app with mocked db, request and response to test
app := &api{db}
req, err := http.NewRequest("GET", "http://localhost/posts", nil)
if err != nil {
t.Fatalf("an error '%s' was not expected while creating request", err)
}
w := httptest.NewRecorder()
// before we actually execute our api function, we need to expect required DB actions
mock.ExpectQuery("^SELECT (.+) FROM posts$").WillReturnError(fmt.Errorf("some error"))
// now we execute our request
app.posts(w, req)
if w.Code != 500 {
t.Fatalf("expected status code to be 500, but got: %d", w.Code)
}
data := struct {
Error string
}{"failed to fetch posts: some error"}
app.assertJSON(w.Body.Bytes(), data, t)
// we make sure that all expectations were met
if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("there were unfulfilled expectations: %s", err)
}
}
|