Skip to content

Instantly share code, notes, and snippets.

@podhmo
Created December 25, 2022 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save podhmo/f03319ced8e40aaaa83893c61b58bcc4 to your computer and use it in GitHub Desktop.
Save podhmo/f03319ced8e40aaaa83893c61b58bcc4 to your computer and use it in GitHub Desktop.
package fakeclient_test
import (
"bytes"
"encoding/json"
"fmt"
"log"
"net/http"
"net/http/httptest"
"testing"
"time"
)
func TestSum(t *testing.T) {
mux := new(http.ServeMux)
mux.HandleFunc("/add", func(w http.ResponseWriter, r *http.Request) {
var input AddInput
if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
w.WriteHeader(400)
return
}
output := AddOutput{N: input.X + input.Y}
w.Header().Set("content-type", "application/json")
b, err := json.MarshalIndent(output, "", " ")
if err != nil {
w.WriteHeader(500)
return
}
w.Write(b)
})
fakeClient := &http.Client{Timeout: 1000 * time.Millisecond, Transport: &Interceptor{Handler: mux}}
api := NewAPI(fakeClient)
want := 55
got, err := Sum(api, 1, 10)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if want != got {
t.Errorf("sum(1,10), want %d, but got %d", want, got)
}
}
type Interceptor struct {
Handler http.Handler
}
func (i *Interceptor) RoundTrip(req *http.Request) (*http.Response, error) {
rec := httptest.NewRecorder()
i.Handler.ServeHTTP(rec, req)
return rec.Result(), nil
}
type API struct {
baseAPI string
client *http.Client
}
func NewAPI(client *http.Client) *API {
return &API{
baseAPI: "http://example.net",
client: client,
}
}
type AddInput struct {
X int `json:"x"`
Y int `json:"y"`
}
type AddOutput struct {
N int `json:"n"`
}
func (api *API) Add(x, y int) (int, error) {
input := AddInput{X: x, Y: y}
payload := new(bytes.Buffer)
if err := json.NewEncoder(payload).Encode(input); err != nil {
return 0, err // encode error
}
res, err := api.client.Post(api.baseAPI+"/add", "application/json", payload)
if err != nil {
return 0, err // connection error
}
if res.StatusCode != 200 {
return 0, fmt.Errorf("ng status: %d", res.StatusCode) // status error
}
defer func() {
if err := res.Body.Close(); err != nil {
log.Printf("add: response body close: %+v", err)
}
}()
var output AddOutput
if err := json.NewDecoder(res.Body).Decode(&output); err != nil {
return 0, err // decode error
}
return output.N, nil
}
func Sum(api *API, start, end int) (n int, err error) {
for i := 0; i <= end; i++ {
n, err = api.Add(n, i)
if err != nil {
return n, err
}
}
return n, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment