gock icon indicating copy to clipboard operation
gock copied to clipboard

Non-matching path not detected

Open stuart-mclaren opened this issue 5 years ago • 2 comments

The following test passes: even though "/b" is the expected path and "/bar" is the actual path:

func TestA(t *testing.T) {                                                      
    // Passes -- but shouldn't                                                  
    defer gock.Off()                                                            
                                                                                
    gock.New("http://foo").                                                     
        Get("/b").                                                              
        Reply(http.StatusOK).                                                   
        BodyString("Some text")                                                 
                                                                                
    c := &http.Client{}                                                         
    c.Get("http://foo/bar")                                                     
    assert.Equal(t, true, gock.IsDone())                                        
}

Is this expected behaviour?

Using a regex ($) seems to give the behaviour I'd expect (for matching and non-matching cases):

func TestB(t *testing.T) {                                                      
    // Fails -- correctly                                                       
    defer gock.Off()                                                            
                                                                                
    gock.New("http://foo").                                                     
        Get("/b($)").                                                           
        Reply(http.StatusOK).                                                   
        BodyString("Some text")                                                 
                                                                                
    c := &http.Client{}                                                         
    c.Get("http://foo/bar")                                                     
    assert.Equal(t, true, gock.IsDone())                                        
}

Thanks.

stuart-mclaren avatar Feb 14 '19 18:02 stuart-mclaren

Had the same problem and saw this issue. Digging a bit through the code it seems it the behaviour is expected: If actual path is not equal to the expected path, then a regex comparison is done, see https://github.com/h2non/gock/blob/48ac21d/matchers.go#L67-L73:

// MatchPath matches the HTTP URL path of the given request.
func MatchPath(req *http.Request, ereq *Request) (bool, error) {
	if req.URL.Path == ereq.URLStruct.Path {
		return true, nil
	}
	return regexp.MatchString(ereq.URLStruct.Path, req.URL.Path)
}

It would be nice if the documentation/godoc of the methods mention that regex match is done...

kampde avatar Feb 16 '22 15:02 kampde

I've had the same problem but with the hostname and regex matching it as well, on account of https://github.com/h2non/gock/blob/48ac21d/matchers.go#L56-L65.

This means that all of the following will match, which wasn't really expected, particularly given the . is being interpreted as a regex any-character match:

gock.New("https://example.com").Reply(200)

http.Get("https://example.comx")
http.Get("https://foo.example.com.zz")
http.Get("https://fooexample.com")
http.Get("https://examplexcom.foo")

// and any other request with a host that contains "example.com" where the . can be any char since it's regex

davidjb avatar Jan 10 '24 01:01 davidjb