Skip to content

Commit

Permalink
Improve web testing (#21)
Browse files Browse the repository at this point in the history
* Change and extend web body helpers

* Fix linter errors

* Fix linter errors

* Fix web response status

* Extend documentation

* Integrate httptest

* Fix request creation

* Add changelog entry

* Extend web tests for convenience

* Improve convenience post methods

* Add changes to CHANGELOG
  • Loading branch information
themue authored Dec 26, 2021
1 parent 1726559 commit 8edbfd3
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## v0.6.4

* (C) Web simulator now provides some convenience methods

## v0.6.3

* (C) Web package now uses httptest package
Expand Down
36 changes: 36 additions & 0 deletions web/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,40 @@ func (s *Simulator) Do(r *http.Request) (*http.Response, error) {
return w.Result(), nil
}

// Get conveniently executes a simple GET request.
func (s *Simulator) Get(target string) (*http.Response, error) {
req := s.CreateRequest(http.MethodGet, target, nil)

return s.Do(req)
}

// Post conveniently executes a simple POST request.
func (s *Simulator) Post(target, contentType string, body io.Reader) (*http.Response, error) {
req := s.CreateRequest(http.MethodPost, target, body)

return s.Do(req)
}

// PostText conveniently executes a simple POST request with the given string body.
func (s *Simulator) PostText(target, body string) (*http.Response, error) {
req := s.CreateRequest(http.MethodPost, target, nil)
req.Header.Set("Content-Type", "text/plain")

StringToBody(body, req)

return s.Do(req)
}

// PostJSON conveniently executes a simple POST request with the given interface body.
func (s *Simulator) PostJSON(target string, body interface{}) (*http.Response, error) {
req := s.CreateRequest(http.MethodPost, target, nil)
req.Header.Set("Content-Type", "application/json")

if err := JSONToBody(body, req); err != nil {
return nil, err
}

return s.Do(req)
}

// EOF
63 changes: 61 additions & 2 deletions web/web_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func TestJSONBody(t *testing.T) {
_, err = w.Write(b)
assert.NoError(err)
})
req := s.CreateRequest(http.MethodGet, "https://localhost:8080/", nil)
req := s.CreateRequest(http.MethodPost, "https://localhost:8080/", nil)
err := web.JSONToBody(data{"correct", 12345, true}, req)
assert.NoError(err)
resp, err := s.Do(req)
Expand All @@ -87,15 +87,74 @@ func TestJSONBody(t *testing.T) {
assert.NoError(err)
})
req = s.CreateRequest(http.MethodGet, "https://localhost:8080/", nil)
assert.NoError(err)
err = web.JSONToBody(data{"correct", 12345, true}, req)
assert.NoError(err)
resp, err = s.Do(req)
assert.NoError(err)
assert.Equal(resp.StatusCode, http.StatusOK)
err = web.BodyToJSON(resp, &obj)
assert.ErrorContains(err, "invalid character")
}

// TestConvenience verifies the correct working of the convenient helper
// methods.
func TestConvenience(t *testing.T) {
assert := asserts.NewTesting(t, asserts.FailStop)

// Correctly marshalling data.
s := web.NewFuncSimulator(func(w http.ResponseWriter, r *http.Request) {
contentType := r.Header.Get("content-type")
w.Header().Add("content-type", contentType)
if r.Method == http.MethodGet {
b := []byte(`{"A":"first", "B":54321, "C":false}`)
_, err := w.Write(b)
assert.NoError(err)
return
}
b, err := ioutil.ReadAll(r.Body)
assert.NoError(err)
_, err = w.Write(b)
assert.NoError(err)
})

// Step 1: GET.
resp, err := s.Get("https://localhost:8080/")
assert.NoError(err)
assert.Equal(resp.StatusCode, http.StatusOK)
var obj data
err = web.BodyToJSON(resp, &obj)
assert.NoError(err)
assert.Equal(obj.A, "first")
assert.Equal(obj.B, 54321)
assert.Equal(obj.C, false)

// Steo 2: Simple POST.
resp, err = s.Post("https://localhost:8080/", "text/plain", strings.NewReader("second"))
assert.NoError(err)
assert.Equal(resp.StatusCode, http.StatusOK)
text, err := web.BodyToString(resp)
assert.NoError(err)
assert.Equal(text, "second")

// Steo 3: Simple POST text string.
resp, err = s.PostText("https://localhost:8080/", "third")
assert.NoError(err)
assert.Equal(resp.StatusCode, http.StatusOK)
assert.Equal(resp.Header.Get("content-type"), "text/plain")
text, err = web.BodyToString(resp)
assert.NoError(err)
assert.Equal(text, "third")

// Steo 4: Simple POST JSON object.
resp, err = s.PostJSON("https://localhost:8080/", data{"fourth", 10101, true})
assert.NoError(err)
assert.Equal(resp.Header.Get("content-type"), "application/json")
assert.Equal(resp.StatusCode, http.StatusOK)
err = web.BodyToJSON(resp, &obj)
assert.NoError(err)
assert.Equal(obj.A, "fourth")
assert.Equal(obj.B, 10101)
assert.Equal(obj.C, true)
}

// TestResponseCode verifies that the status code cannot be changed after
Expand Down

0 comments on commit 8edbfd3

Please sign in to comment.