Skip to content

Commit 69f322b

Browse files
steinfletcherh2non
authored andcommitted
feat(gock): add gock.Observe to support inspection of the outgoing intercepted HTTP traffic (#38)
1 parent db99161 commit 69f322b

File tree

6 files changed

+92
-1
lines changed

6 files changed

+92
-1
lines changed

.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ before_install:
1414
- go get -u gopkg.in/h2non/gentleman.v1
1515
- go get -u -v github.com/axw/gocov/gocov
1616
- go get -u -v github.com/mattn/goveralls
17-
- go get -u -v github.com/golang/lint/golint
17+
- go get -v -u golang.org/x/lint/golint
1818
- mkdir -p $GOPATH/src/gopkg.in/h2non/gock.v1
1919
- cp -r . $GOPATH/src/gopkg.in/h2non/gock.v1
2020

README.md

+27
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,33 @@ func main() {
303303
}
304304
```
305305

306+
#### Debug intercepted http requests
307+
308+
```go
309+
package main
310+
311+
import (
312+
"bytes"
313+
"gopkg.in/h2non/gock.v1"
314+
"net/http"
315+
)
316+
317+
func main() {
318+
defer gock.Off()
319+
gock.Observe(gock.DumpRequest)
320+
321+
gock.New("http://foo.com").
322+
Post("/bar").
323+
MatchType("json").
324+
JSON(map[string]string{"foo": "bar"}).
325+
Reply(200)
326+
327+
body := bytes.NewBuffer([]byte(`{"foo":"bar"}`))
328+
http.Post("http://foo.com/bar", "application/json", body)
329+
}
330+
331+
```
332+
306333
## Hacking it!
307334

308335
You can easily hack `gock` defining custom matcher functions with own matching rules.

_examples/observe/observe.go

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"gopkg.in/h2non/gock.v1"
6+
"net/http"
7+
)
8+
9+
func main() {
10+
defer gock.Off()
11+
gock.Observe(gock.DumpRequest)
12+
13+
gock.New("http://foo.com").
14+
Post("/bar").
15+
MatchType("json").
16+
JSON(map[string]string{"foo": "bar"}).
17+
Reply(200)
18+
19+
body := bytes.NewBuffer([]byte(`{"foo":"bar"}`))
20+
http.Post("http://foo.com/bar", "application/json", body)
21+
}

gock.go

+21
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package gock
22

33
import (
4+
"fmt"
45
"net/http"
6+
"net/http/httputil"
57
"net/url"
68
"regexp"
79
"sync"
@@ -14,8 +16,20 @@ var mutex = &sync.Mutex{}
1416
var config = struct {
1517
Networking bool
1618
NetworkingFilters []FilterRequestFunc
19+
Observer ObserverFunc
1720
}{}
1821

22+
// ObserverFunc is implemented by users to inspect the outgoing intercepted HTTP traffic
23+
type ObserverFunc func(*http.Request, Mock)
24+
25+
// DumpRequest is a default implementation of ObserverFunc that dumps
26+
// the HTTP/1.x wire representation of the http request
27+
var DumpRequest ObserverFunc = func(request *http.Request, mock Mock) {
28+
bytes, _ := httputil.DumpRequestOut(request, true)
29+
fmt.Println(string(bytes))
30+
fmt.Printf("\nMatches: %v\n---\n", mock != nil)
31+
}
32+
1933
// track unmatched requests so they can be tested for
2034
var unmatchedRequests = []*http.Request{}
2135

@@ -92,6 +106,13 @@ func OffAll() {
92106
CleanUnmatchedRequest()
93107
}
94108

109+
// Observe provides a hook to support inspection of the request and matched mock
110+
func Observe(fn ObserverFunc) {
111+
mutex.Lock()
112+
defer mutex.Unlock()
113+
config.Observer = fn
114+
}
115+
95116
// EnableNetworking enables real HTTP networking
96117
func EnableNetworking() {
97118
mutex.Lock()

gock_test.go

+17
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,23 @@ func TestMockRegExpMatching(t *testing.T) {
412412
st.Expect(t, string(body)[:13], `{"foo":"bar"}`)
413413
}
414414

415+
func TestObserve(t *testing.T) {
416+
defer after()
417+
var observedRequest *http.Request
418+
var observedMock Mock
419+
Observe(func(request *http.Request, mock Mock) {
420+
observedRequest = request
421+
observedMock = mock
422+
})
423+
New("http://observe-foo.com").Reply(200)
424+
req, _ := http.NewRequest("POST", "http://observe-foo.com", nil)
425+
426+
http.DefaultClient.Do(req)
427+
428+
st.Expect(t, observedRequest.Host, "observe-foo.com")
429+
st.Expect(t, observedMock.Request().URLStruct.Host, "observe-foo.com")
430+
}
431+
415432
func after() {
416433
Flush()
417434
Disable()

transport.go

+5
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ func (m *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
6262
return nil, err
6363
}
6464

65+
// Invoke the observer with the intercepted http.Request and matched mock
66+
if config.Observer != nil {
67+
config.Observer(req, mock)
68+
}
69+
6570
// Verify if should use real networking
6671
networking := shouldUseNetwork(req, mock)
6772
if !networking && mock == nil {

0 commit comments

Comments
 (0)