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

Update resty usage example + Add JsonString responder #150

Open
takanuva15 opened this issue Mar 29, 2024 · 1 comment
Open

Update resty usage example + Add JsonString responder #150

takanuva15 opened this issue Mar 29, 2024 · 1 comment

Comments

@takanuva15
Copy link

Hi, thanks for maintaining this awesome http testing library. I am using Resty to make API calls, and their documentation links to this library for mocking Client returns.

However, I am using [email protected], which no longer offers the resty.DefaultClient which the test example in the README is currently showing:

var _ = BeforeSuite(func() {
  // block all HTTP requests
  httpmock.ActivateNonDefault(resty.DefaultClient.GetClient())
})

Instead, we have to call resty.New() and specify our own defaults. This works fine, but it doesn't work as a drop-in with the current test example, because the content-type is no longer set to application/json by default. I spent a bunch of time debugging why the readme example didn't work until I figured out that httpmock.NewStringResponder doesn't set the content/type header on the httpmock.StringResponse it's making internally. Thus Resty does not serialize the string to json automatically, so it just throws nil for the test example which is very difficult to debug.

To work around this, I had to make my own custom string responder like so:

// NewJsonStringResponder returns an httpmock Responder that resty can use to
// automatically deserialize a JSON string into a struct
func NewJsonStringResponder(status int, body string) Responder {
	res := NewStringResponse(status, body)
	res.Header.Set("Content-Type", "application/json")
	return ResponderFromResponse(res)
}

Then, it finally works with the Resty example:

client := resty.New()

var _ = BeforeSuite(func() {
  // block all HTTP requests
  httpmock.ActivateNonDefault(client.GetClient())
})

...

var _ = Describe("Articles", func() {
  It("returns a list of articles", func() {
    fixture := `{"status":{"message": "Your message", "code": 200}}`
    responder := mypackage.NewJsonStringResponder(200, fixture)
   ...
   _, err := client.R().SetResult(articleObject).Get(fakeUrl)
  })
})

Thus, I would like to request two things:

  1. Can the resty usage example be updated to work with resty@v2?
  2. Can we add NewJsonStringResponder into the httpmock library so that library users can automatically use json strings for mock responses out-of-the-box (as the resty example intended to demonstrate)? (Since json is the most common language for APIs, it makes sense to make a json-string responder function easily accessible to users without forcing them to redeclare the function I described above)

As a side note, there is a dedicated article on Medium on this library that describes the exact problem I explained above and shows the same workaround I pasted above: https://olegcodes.medium.com/mocking-http-services-in-go-6b76215a81c9

@maxatome
Copy link
Collaborator

maxatome commented Apr 2, 2024

Hello,

  1. of course! could you please fill in a PR?
  2. I don't think a new function is needed as you already have several ways to do it:
    httpmock.NewStringResponder(200, `{"status":{}}`).
      HeaderSet(http.Header{"Content-Type": {"application/json"}})
    // or
    httpmock.NewJsonResponder(200, json.RawMessage(`{"status":{}}`))

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

No branches or pull requests

2 participants