Пример тестирование API HTTP
package apiserver import ( "bytes" "encoding/json" "fmt" "github.com/stretchr/testify/assert" "net/http" "net/http/httptest" "rest_api/internal/app/model" "rest_api/internal/app/store/teststore" "testing" ) func TestServer_HandleCreateUser(t *testing.T) { s := newServer(teststore.New()) testCases := []struct { name string payload interface{} expectedCode int }{ { name: "valid", payload: map[string]interface{}{ "name": "Name", "email": "current@mail.com", "password": "123456", }, expectedCode: http.StatusCreated, }, { name: "empty payload", payload: "invalid", expectedCode: http.StatusBadRequest, }, { name: "invalid email", payload: map[string]interface{}{ "name": "Name", "email": "nenormalmail", "password": "12345", }, expectedCode: http.StatusUnprocessableEntity, }, { name: "invalid password", payload: map[string]interface{}{ "name": "Name", "email": "normal@mail.com", "password":"12345", }, expectedCode: http.StatusUnprocessableEntity, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { b := &bytes.Buffer{} json.NewEncoder(b).Encode(tc.payload) rec := httptest.NewRecorder() req, _ := http.NewRequest(http.MethodPost, "/create", b) s.ServeHTTP(rec, req) assert.Equal(t, tc.expectedCode, rec.Code) }) } } func TestServer_HandleAuthorizeUser(t *testing.T) { s := newServer(teststore.New()) testCases := []struct{ name string payload interface{} expectedCode int }{ { name: "valid", payload: map[string]interface{}{ "email": "test@example.com", "password": "password", }, expectedCode: http.StatusOK, }, { name: "invalid payload", payload: "invalid", expectedCode: http.StatusBadRequest, }, { name: "invalid user", payload: map[string]interface{}{ "email": "test@example.com", "password": "", }, expectedCode: http.StatusForbidden, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { user := map[string]interface{}{ "name": "User", "email": "test@example.com", "password": "password", } resp := struct { Token string `json:"token"` }{} b := &bytes.Buffer{} json.NewEncoder(b).Encode(user) rec := httptest.NewRecorder() req, _ := http.NewRequest(http.MethodPost, "/create", b) s.ServeHTTP(rec, req) json.NewEncoder(b).Encode(tc.payload) rec = httptest.NewRecorder() req, _ = http.NewRequest(http.MethodPost, "/authorize", b) s.ServeHTTP(rec, req) json.NewDecoder(rec.Body).Decode(resp) recToken := resp.Token assert.Equal(t, tc.expectedCode, rec.Code) assert.NotNil(t, recToken) }) } } func TestServer_HandleCreateArticle(t *testing.T) { s := newServer(teststore.New()) testCases := []struct{ name string payload interface{} expectedCode int }{ { name: "valid", payload: map[string]interface{}{ "article_header": "Test Article", "article_text": "Article test text", "author_id": 1, }, expectedCode: http.StatusCreated, }, { name: "invalid", payload: "invalid", expectedCode: http.StatusBadRequest, }, { name: "invalid article text", payload: map[string]interface{}{ "article_header": "Test Article", "article_text": 7, "author_id": 1, }, expectedCode: http.StatusBadRequest, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { us := map[string]interface{}{ "name": "User", "email": "user@mail.com", "password": "123456", } resp := &struct { User *model.User `json:"user"` Token string `json:"token"` }{} b := &bytes.Buffer{} json.NewEncoder(b).Encode(us) rec := httptest.NewRecorder() req, _ := http.NewRequest(http.MethodPost, "/create", b) s.ServeHTTP(rec, req) json.NewDecoder(rec.Body).Decode(resp) token := fmt.Sprintf("Baerer %s", resp.Token) json.NewEncoder(b).Encode(tc.payload) req, _ = http.NewRequest(http.MethodPost, "/private/create/article", b) rec = httptest.NewRecorder() req.Header.Add("Authorization", token) s.ServeHTTP(rec, req) assert.Equal(t, tc.expectedCode, rec.Code) }) } } func TestServer_HandleFindArticleByHeading(t *testing.T) { ts := teststore.New() ts.Article().CreateArticle(model.TestArticle(t, 5)) s := newServer(ts) testCases := []struct{ name string payload interface{} expectedCode int }{ { name: "valid", payload: map[string]interface{}{ "article_heading": "TestArticle", }, expectedCode: http.StatusOK, }, { name: "invalid article header", payload: map[string]interface{}{ "article_heading": "Article", }, expectedCode: http.StatusUnprocessableEntity, }, { name: "invalid request", payload: map[string]interface{}{ "article_heading": 1, }, expectedCode: http.StatusBadRequest, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { b := &bytes.Buffer{} json.NewEncoder(b).Encode(tc.payload) rec := httptest.NewRecorder() req, _ := http.NewRequest(http.MethodGet, "/find/article", b) s.ServeHTTP(rec, req) assert.Equal(t, tc.expectedCode, rec.Code) }) } } func TestServer_HandleChangeArticle(t *testing.T) { ts := teststore.New() article := model.TestArticle(t, 5) ts.Article().CreateArticle(article) s := newServer(ts) testCases := []struct{ name string payload interface{} expectedCode int }{ { name: "valid", payload: map[string]interface{}{ "id" : article.ID, "article_header": "Updated TestArticle", "article_text": "updated article text", }, expectedCode: http.StatusOK, }, { name: "invalid", payload: "invalid", expectedCode: http.StatusBadRequest, }, { name: "invalid id", payload: map[string]interface{}{ "id" : 1, "article_header": "Updated TestArticle", "article_text": "updated article text", }, expectedCode: http.StatusUnprocessableEntity, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { us := map[string]interface{}{ "name": "User", "email": "user@mail.com", "password": "123456", } resp := &struct { User *model.User `json:"user"` Token string `json:"token"` }{} b := &bytes.Buffer{} json.NewEncoder(b).Encode(us) rec := httptest.NewRecorder() req, _ := http.NewRequest(http.MethodPost, "/create", b) s.ServeHTTP(rec, req) json.NewDecoder(rec.Body).Decode(resp) token := fmt.Sprintf("Baerer %s", resp.Token) json.NewEncoder(b).Encode(tc.payload) req, _ = http.NewRequest(http.MethodPut, "/private/change/article", b) rec = httptest.NewRecorder() req.Header.Add("Authorization", token) s.ServeHTTP(rec, req) assert.Equal(t, tc.expectedCode, rec.Code) }) } } func TestServer_HandleDeleteArticle(t *testing.T) { ts := teststore.New() article := model.TestArticle(t, 5) ts.Article().CreateArticle(article) s := newServer(ts) testCases := []struct{ name string payload interface{} expectedCode int }{ { name: "valid", payload: map[string]interface{}{ "id" : article.ID, }, expectedCode: http.StatusOK, }, { name: "invalid", payload: "invalid", expectedCode: http.StatusBadRequest, }, { name: "invalid id", payload: map[string]interface{}{ "id" : 1, }, expectedCode: http.StatusUnprocessableEntity, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { us := map[string]interface{}{ "name": "User", "email": "user@mail.com", "password": "123456", } resp := &struct { User *model.User `json:"user"` Token string `json:"token"` }{} b := &bytes.Buffer{} json.NewEncoder(b).Encode(us) rec := httptest.NewRecorder() req, _ := http.NewRequest(http.MethodPost, "/create", b) s.ServeHTTP(rec, req) json.NewDecoder(rec.Body).Decode(resp) token := fmt.Sprintf("Baerer %s", resp.Token) json.NewEncoder(b).Encode(tc.payload) req, _ = http.NewRequest(http.MethodDelete, "/private/delete/article", b) rec = httptest.NewRecorder() req.Header.Add("Authorization", token) s.ServeHTTP(rec, req) assert.Equal(t, tc.expectedCode, rec.Code) }) } }
https://github.com/backspacesh/notebook_api/blob/5bdd97a7b98f85a84d6af4bb51da9d128a520384/internal/app/apiserver/server_internal_test.go