github.com/agilebits/godog@v0.7.9/examples/api/api_test.go (about) 1 package main 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "net/http/httptest" 8 9 "github.com/DATA-DOG/godog" 10 "github.com/DATA-DOG/godog/gherkin" 11 ) 12 13 type apiFeature struct { 14 resp *httptest.ResponseRecorder 15 } 16 17 func (a *apiFeature) resetResponse(interface{}) { 18 a.resp = httptest.NewRecorder() 19 } 20 21 func (a *apiFeature) iSendrequestTo(method, endpoint string) (err error) { 22 req, err := http.NewRequest(method, endpoint, nil) 23 if err != nil { 24 return 25 } 26 27 // handle panic 28 defer func() { 29 switch t := recover().(type) { 30 case string: 31 err = fmt.Errorf(t) 32 case error: 33 err = t 34 } 35 }() 36 37 switch endpoint { 38 case "/version": 39 getVersion(a.resp, req) 40 default: 41 err = fmt.Errorf("unknown endpoint: %s", endpoint) 42 } 43 return 44 } 45 46 func (a *apiFeature) theResponseCodeShouldBe(code int) error { 47 if code != a.resp.Code { 48 return fmt.Errorf("expected response code to be: %d, but actual is: %d", code, a.resp.Code) 49 } 50 return nil 51 } 52 53 func (a *apiFeature) theResponseShouldMatchJSON(body *gherkin.DocString) (err error) { 54 var expected, actual []byte 55 var exp, act interface{} 56 57 // re-encode expected response 58 if err = json.Unmarshal([]byte(body.Content), &exp); err != nil { 59 return 60 } 61 if expected, err = json.MarshalIndent(exp, "", " "); err != nil { 62 return 63 } 64 65 // re-encode actual response too 66 if err = json.Unmarshal(a.resp.Body.Bytes(), &act); err != nil { 67 return 68 } 69 if actual, err = json.MarshalIndent(act, "", " "); err != nil { 70 return 71 } 72 73 // the matching may be adapted per different requirements. 74 if len(actual) != len(expected) { 75 return fmt.Errorf( 76 "expected json length: %d does not match actual: %d:\n%s", 77 len(expected), 78 len(actual), 79 string(actual), 80 ) 81 } 82 83 for i, b := range actual { 84 if b != expected[i] { 85 return fmt.Errorf( 86 "expected JSON does not match actual, showing up to last matched character:\n%s", 87 string(actual[:i+1]), 88 ) 89 } 90 } 91 return 92 } 93 94 func FeatureContext(s *godog.Suite) { 95 api := &apiFeature{} 96 97 s.BeforeScenario(api.resetResponse) 98 99 s.Step(`^I send "(GET|POST|PUT|DELETE)" request to "([^"]*)"$`, api.iSendrequestTo) 100 s.Step(`^the response code should be (\d+)$`, api.theResponseCodeShouldBe) 101 s.Step(`^the response should match json:$`, api.theResponseShouldMatchJSON) 102 }