h2non / gock

HTTP traffic mocking and testing made easy in Go ༼ʘ̚ل͜ʘ̚༽
https://pkg.go.dev/github.com/h2non/gock
MIT License
2.04k stars 106 forks source link

Different JSON array body matches #81

Open stevenferrer opened 3 years ago

stevenferrer commented 3 years ago

First, thank you for making this amazing project!

I've noticed that when I try to match a request body that is an array, the requests are still matching even though the mock and request body are clearly different.

baseURL := "http://foo.com"
gock.New(baseURL).
    Post("/bar").
    MatchType("json").
    BodyString(`[{"foo":"bar"},{"fizz":"buzz"}]`).
    Reply(http.StatusOK).
    JSON(map[string]interface{})

req, _ := http.NewRequest(http.MethodPost, baseURL+"/bar", bytes.NewBuffer([]byte(`[{"foo":"baz"}]`)))
res, err := http.DefaultClient.Do(req)

On the code, before getting into the lines where the json.Unmarshal is called, I've noticed that the matcher already returns true in the regexp.MatchString part.

I've tried to come-up with a fix, but it seems that it's gonna be difficult without knowing whether the request body contains regular expressions or just a normal JSON.

denysvitali commented 1 year ago

I just noticed the same and was confused for a second.

My input:

Request Body

{"data": {"a": "b"}}

Expected Body

{"a": "b"}

The issue happens here: https://github.com/h2non/gock/blob/48ac21df559bb9539dc0249c7f0d3a9099f159ec/matchers.go#L188-L198

bodyStr has value of {"data": {"a": "b"}} matchStr has a value of {"a": "b"}

This sadly makes the request match, and thus makes some of my tests pass although they should fail with an unmatched request error :(

I would suggest to not match the body by regex, at all, unless the user really wants to (maybe we can create a method for that, like MatchBodyRegex or similar.

Having a MatchBody method that sneakly does regex matching is error prone and can cause huge issues, especially in such an important mocking library.