Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Body and Rawbody #600

Closed
Joseph94m opened this issue Nov 10, 2022 · 2 comments · Fixed by #724
Closed

Body and Rawbody #600

Joseph94m opened this issue Nov 10, 2022 · 2 comments · Fixed by #724
Assignees
Milestone

Comments

@Joseph94m
Copy link

I've been banging my head against the wall for a day, so I thought why not swing by and say hi 👯

There are two main subjects I will tackle in this post - not necessarily issues or bugs. Maybe just in need of enlightenment.

1- In resty v2, Body() and RawBody() are defined as follows:

func (r *Response) Body() []byte {
	if r.RawResponse == nil {
		return []byte{}
	}
	return r.body
}

func (r *Response) RawBody() io.ReadCloser {
	if r.RawResponse == nil {
		return nil
	}
	return r.RawResponse.Body
}

It seems weird to me that we check for RawResponse == nil in Body(), why not just return r.body? Maybe,I'm just being really pedantic here but hey!


2- I came across 1- as I was trying to mock GET requests performed through resty for testing purposes...

Normally I use httpmock, but for my current project I wanted to to have 2 levels of testing, 1/ with httpmock and 2/ more of a low level testing using my own implementation with custom responses.

Through a custom request handler, I have:

type HTTPHandler struct {
	ErrorCodes map[string]error
	Responses  map[string]resty.Response
	client     *resty.Client
}

var Handler = &HTTPHandler{}
// sets the resty client in the Handler
func NewHTTPHandler(client *resty.Client) *HTTPHandler {
	if Handler.ErrorCodes == nil {
		Handler.ErrorCodes = map[string]error{}
	}
	if Handler.Responses == nil {
		Handler.Responses = map[string]resty.Response{}
	}
	Handler.client = client
	return Handler
}

// sets a custom http response, to be returned in the GET function based on the URL key
func (h *HTTPHandler) SetCustomResponse(url string, statusCode int, status string, body string) {
	// create body_ from body string
	body_ := io.NopCloser(strings.NewReader(body))
	h.Responses[url] = resty.Response{
		Request: h.client.R(),
		RawResponse: &http.Response{
			StatusCode:    statusCode,
			Status:        status,
			Body:          body_,
			ContentLength: int64(len(body)),
		},
	}
}

func (h *HTTPHandler) Do(url string) (*resty.Response, error) {
	var response *resty.Response
	if val, ok := h.Responses[url]; ok {
		response = &val
	}
	return response, h.ErrorCodes[url]
}

When called, for example:

expectedStatus = 400
expectedStatusText = "Bad Request"
expectedBody = `{"message": "Bad Request - test"}`
mockHandler.CustomResponse("http://test.com/health", expectedStatus, fmt.Sprintf("%d %s", expectedStatus, expectedStatusText), expectedBody)

Exeucting the GET function returns a response. If i call response.Body(), I will receive an empty array as response.Body() returns r.body and I cannot set this variable because it is unexported.

Is there a way I can set a custom body field directly in the Response structure instead of the RawResponse? I've banged my head against this trying to find workarounds with the Writer and Reader interfaces in resty but no luck.

Or am I doing some anti-pattern here? Maybe I should just use response.RawBody() instead of response.Body() but that seems awfully barbaric as we call response.Body() in our main functions, and I would hate to swap it with response.RawBody() just so that I can test it....

Thanks !

@jeevatkm
Copy link
Member

@Joseph94m Thanks for reaching out. I understand the details you have given about empty array. I have looked back and found the commit I did this change: 506bd6a.

Feel free to share improvement suggestion.

@jeevatkm
Copy link
Member

jeevatkm commented Oct 8, 2023

@Joseph94m I have added Response.SetBody(b []byte) will be released in v2.10.0. I should have done it earlier.
Currently, it's available in v2.10.0-rc.2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging a pull request may close this issue.

2 participants