package main import ( "encoding/json" "fmt" "net/http" "net/http/httptest" "github.com/DATA-DOG/godog" "github.com/DATA-DOG/godog/gherkin" ) type apiFeature struct { resp *httptest.ResponseRecorder } func (a *apiFeature) resetResponse(interface{}) { a.resp = httptest.NewRecorder() } func (a *apiFeature) iSendrequestTo(method, endpoint string) (err error) { req, err := http.NewRequest(method, endpoint, nil) if err != nil { return } // handle panic defer func() { switch t := recover().(type) { case string: err = fmt.Errorf(t) case error: err = t } }() switch endpoint { case "/version": getVersion(a.resp, req) default: err = fmt.Errorf("unknown endpoint: %s", endpoint) } return } func (a *apiFeature) theResponseCodeShouldBe(code int) error { if code != a.resp.Code { return fmt.Errorf("expected response code to be: %d, but actual is: %d", code, a.resp.Code) } return nil } func (a *apiFeature) theResponseShouldMatchJSON(body *gherkin.DocString) (err error) { var expected, actual []byte var exp, act interface{} // re-encode expected response if err = json.Unmarshal([]byte(body.Content), &exp); err != nil { return } if expected, err = json.MarshalIndent(exp, "", " "); err != nil { return } // re-encode actual response too if err = json.Unmarshal(a.resp.Body.Bytes(), &act); err != nil { return } if actual, err = json.MarshalIndent(act, "", " "); err != nil { return } // the matching may be adapted per different requirements. if len(actual) != len(expected) { return fmt.Errorf( "expected json length: %d does not match actual: %d:\n%s", len(expected), len(actual), string(actual), ) } for i, b := range actual { if b != expected[i] { return fmt.Errorf( "expected JSON does not match actual, showing up to last matched character:\n%s", string(actual[:i+1]), ) } } return } func FeatureContext(s *godog.Suite) { api := &apiFeature{} s.BeforeScenario(api.resetResponse) s.Step(`^I send "(GET|POST|PUT|DELETE)" request to "([^"]*)"$`, api.iSendrequestTo) s.Step(`^the response code should be (\d+)$`, api.theResponseCodeShouldBe) s.Step(`^the response should match json:$`, api.theResponseShouldMatchJSON) }