Documentation ¶
Overview ¶
Package RESTit provides helps to those who want to write an integration test program for their JSON-based RESTful APIs.
The aim is to make these integration readable highly re-usable, and yet easy to modify.
To use, you first have to implement the `TestRespond` interface for the REST server response that you're expecting.
In Go, json contents are usually unmarshaled to structs. What you need to do is implement 4 methods to the struct type.
For example:
type ExmplResp struct { Status string `json:"status"` Result []Stuff `json:"result"` } func (r *ExmplResp) Count() int { return len(r.Result) } func (r *ExmplResp) NthValid(n int) (err error) { // some test to see nth record is valid // such as: if r.Result[n].StuffId == 0 { return fmt.Errorf( "StuffId should not be 0") } return } func (r *ExmplResp) GetNth(n int) (item interface{}, err error) { // return the nth item return Result[n] } func (r *ExmplResp) Match( a interface{}, b interface{}) ( match bool, err error) { // cast a and b back to Stuff real_a = a.(Stuff) real_b = b.(Stuff) // some test to check if real_a equals real_b // ... } func (r *ExmplResp) Reset() { r.Status = "" r.Result = make([]Stuff, 0) } You can then test your RESTful API like this: import restit "github.com/go-restit/restit/v1" // create a tester for your stuff // first parameter is a human readable name that will // appear on error second parameter is the base URL to // the API entry point stuff := restit.Rest( "Stuff", "http://foobar:8080/api/stuffs") // some parameters we'll use var result restit.TestResult var test restit.TestCase var response ExmplResp // some random stuff for test // for example, stuffToCreate = Stuff{ Name: "apple", Color: "red", } stuffToUpdate = Stuff{ Name: "orange", Color: "orange", } // here we add some dummy security measures // or you may add any parameters you like securityInfo := napping.Params{ "username": "valid_user", "token": "some_security_token", } // -------- Test Create -------- // 1. create the stuff test = stuffAPI. Create(&stuffToCreate). AddHeader("Authorization", "Some token"). WithParams(&securityInfo). WithResponseAs(&response). ExpectResultCount(1). ExpectResultsValid(). ExpectResultNth(0, &stuffToCreate). ExpectResultsToPass( "Custom Test", func (r Response) error { // some custom test you may want to run // ... }) result, err := test.Run() if err != nil { // you may add more verbose output for // inspection fmt.Printf("Failed creating stuff!!!!\n") fmt.Printf("Please inspect the Raw Response: " + result.RawText()) // or you can simply: panic(err) } // id of the just created stuff // for reference of later tests stuffId := response.Result[0].StuffId stuffToCreate.StuffId = stuffId stuffToUpdate.StuffId = stuffId // 2. test the created stuff test = stuffAPI. TestRetrieve(fmt.Sprintf("%d", stuffId)). WithResponseAs(&response). ExpectResultCount(1). ExpectResultsValid(). ExpectResultNth(0, &stuffToCreate) // A short hand to just panic on any error result = test.RunOrPanic() // -------- Test Update -------- // 1. update the stuff result = stuffAPI. Update(&stuffToUpdate, fmt.Sprintf("%d", stuffId)). WithResponseAs(&response). WithParams(&securityInfo). ExpectResultCount(1). ExpectResultsValid(). ExpectResultNth(0, &stuffToUpdate). RunOrPanic() // Yes, you can be this lazy // 2. test the updated stuff result = stuffAPI. Retrieve(fmt.Sprintf("%d", stuffId)). WithResponseAs(&response). ExpectResultCount(1). ExpectResultsValid(). ExpectResultNth(0, &stuffToUpdate). RunOrPanic() // -------- Test Delete -------- // delete the stuff result = stuffAPI. Delete(fmt.Sprintf("%d", stuffId)). WithResponseAs(&response). WithParams(security). ExpectResultCount(1). ExpectResultsValid(). ExpectResultNth(0, &stuffToUpdate). RunOrPanic() // 2. test the deleted stuff result = stuffAPI. Retrieve(fmt.Sprintf("%d", stuffId)). WithResponseAs(&response). ExpectStatus(404). RunOrPanic()
Index ¶
- Variables
- type Case
- func (c *Case) AddHeader(key, value string) *Case
- func (c *Case) ExpectResultCount(n int) *Case
- func (c *Case) ExpectResultCountNot(n int) *Case
- func (c *Case) ExpectResultNth(n int, b interface{}) *Case
- func (c *Case) ExpectResultsToPass(desc string, test func(Response) error) *Case
- func (c *Case) ExpectResultsValid() *Case
- func (c *Case) ExpectStatus(ec int) *Case
- func (c *Case) InitForRun() *Case
- func (c *Case) Run() (r *Result, err error)
- func (c *Case) RunOrPanic() (r *Result)
- func (c *Case) WithErrorAs(e Response) *Case
- func (c *Case) WithParams(p *url.Values) *Case
- func (c *Case) WithResponseAs(r Response) *Case
- type DefaultResponse
- func (p *DefaultResponse) Count() int
- func (p *DefaultResponse) GetNth(n int) (ret interface{}, err error)
- func (p *DefaultResponse) Match(a interface{}, b interface{}) (err error)
- func (p *DefaultResponse) NthValid(n int) (err error)
- func (p *DefaultResponse) Reset()
- func (p *DefaultResponse) SetMatcher(in func(interface{}, interface{}) error)
- func (p *DefaultResponse) SetValidator(in func(interface{}) error)
- type Expectation
- type Matcher
- type Response
- type Result
- type Session
- type Tester
- func (t *Tester) Create(payload interface{}) *Case
- func (t *Tester) Delete(id string) *Case
- func (t *Tester) List(path ...string) *Case
- func (t *Tester) LogDefault() *Tester
- func (t *Tester) LogErrTo(l *log.Logger) *Tester
- func (t *Tester) LogTraceTo(l *log.Logger) *Tester
- func (t *Tester) Retrieve(id string) *Case
- func (t *Tester) Update(id string, payload interface{}) *Case
- type Validator
Constants ¶
This section is empty.
Variables ¶
var ErrorInvalidMatcher = errors.New("Matcher not valid")
var ErrorInvalidType = errors.New("Response item type is not struct")
var ErrorInvalidValidator = errors.New("Validator not valid")
var ErrorNoMatcher = errors.New("Matcher not found. Please set matcher using SetMatcher")
var ErrorNoValidator = errors.New("Validator not found. Please set validator using SetValidator")
var ErrorNthNotFound = errors.New("Nth item not found")
var ErrorUnexpectedItem = errors.New("At least one decoded json item is not map[string]interface{}")
Functions ¶
This section is empty.
Types ¶
type Case ¶
type Case struct { Request *napping.Request Name string Session Session Expectations []Expectation Tester *Tester Result *Result }
func (*Case) ExpectResultCount ¶
Append Test to Expectations Tests if the result count equal to n
func (*Case) ExpectResultCountNot ¶
Append Test to Expectations Tests if the result count not equal to n
func (*Case) ExpectResultNth ¶
Append Test to Expectation Tests if the nth item matches the provided one
func (*Case) ExpectResultsToPass ¶
Append Custom Test to Expectation Allow user to inject user defined tests
func (*Case) ExpectResultsValid ¶
Append Test to Expectations Tests if the item is valid
func (*Case) ExpectStatus ¶
Append Test to Expectations Tests if the response status is
func (*Case) InitForRun ¶
short hand to initialize and enable defaults even if tester is not present
func (*Case) RunOrPanic ¶
To run the test case and panic on error
func (*Case) WithErrorAs ¶
Set the error message to the given interface{}
func (*Case) WithResponseAs ¶
Set the result to the given interface{}
type DefaultResponse ¶
type DefaultResponse map[string]interface{}
DefaultResponse is the default response type to use
func NewResponse ¶
func NewResponse(n string, t interface{}) *DefaultResponse
NewResponse create a new DefaultResponse
func (*DefaultResponse) Count ¶
func (p *DefaultResponse) Count() int
Count counts the number of items in the result
func (*DefaultResponse) GetNth ¶
func (p *DefaultResponse) GetNth(n int) (ret interface{}, err error)
GetNth get the Nth item in the DefaultResponse
func (*DefaultResponse) Match ¶
func (p *DefaultResponse) Match(a interface{}, b interface{}) (err error)
Match test if the nth item is valid
func (*DefaultResponse) NthValid ¶
func (p *DefaultResponse) NthValid(n int) (err error)
NthValid test if the nth item is valid
func (*DefaultResponse) SetMatcher ¶
func (p *DefaultResponse) SetMatcher(in func(interface{}, interface{}) error)
MatchWith set the matcher function. If no matcher function is given, the test will by default fail
func (*DefaultResponse) SetValidator ¶
func (p *DefaultResponse) SetValidator(in func(interface{}) error)
ValidateWith set the validator function. If no validator function is given, the test will by default fail
type Expectation ¶
Expection to the response in a Case
type Response ¶
type Response interface { // count the number of items in the result Count() int // test if the nth item is valid NthValid(int) error // test get the nth item GetNth(int) (interface{}, error) // test if the given 2 items matches Match(interface{}, interface{}) error // reset the result, prevent the problem of null result Reset() }
Response needed to fulfill this interface in order to be tested by RESTit
type Tester ¶
Tester represents an ordinary RESTful entry point
func Rest ¶
Create a tester for an API entry point name string human-readable name of the entry point baseUrl string RESTful API base url