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  }