• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..12-Jul-2019-

History.mdH A D12-Jul-20192 KiB7344

LICENSEH A D12-Jul-20191.1 KiB2520

README.mdH A D12-Jul-20197.5 KiB275204

gock.goH A D12-Jul-20193.6 KiB150100

matcher.goH A D12-Jul-20192.9 KiB11871

matchers.goH A D12-Jul-20195.4 KiB232171

mock.goH A D12-Jul-20193.2 KiB14783

request.goH A D12-Jul-20197.8 KiB284180

responder.goH A D12-Jul-20192.3 KiB10472

response.goH A D12-Jul-20194.8 KiB187118

store.goH A D12-Jul-20191.9 KiB10169

transport.goH A D12-Jul-20192.7 KiB10866

version.goH A D12-Jul-201995 52

README.md

1# gock [![Build Status](https://travis-ci.org/h2non/gock.svg?branch=master)](https://travis-ci.org/h2non/gock) [![GitHub release](https://img.shields.io/badge/version-v1.0-orange.svg?style=flat)](https://github.com/h2non/gock/releases) [![GoDoc](https://godoc.org/github.com/h2non/gock?status.svg)](https://godoc.org/github.com/h2non/gock) [![Coverage Status](https://coveralls.io/repos/github/h2non/gock/badge.svg?branch=master)](https://coveralls.io/github/h2non/gock?branch=master) [![Go Report Card](https://img.shields.io/badge/go_report-A+-brightgreen.svg)](https://goreportcard.com/report/github.com/h2non/gock) [![license](https://img.shields.io/badge/license-MIT-blue.svg)]()
2
3Versatile HTTP mocking made easy in [Go](https://golang.org).
4
5Heavily inspired by [nock](https://github.com/node-nock/nock). See also its Python port, [pook](https://github.com/h2non/pook).
6
7Take a look to the [examples](#examples) to get started.
8
9## Features
10
11- Simple, expressive, fluent API.
12- Semantic DSL for easy HTTP mocks definition.
13- Built-in helpers for easy JSON/XML mocking.
14- Supports persistent and volatile mocks.
15- Full regexp capable HTTP request matching.
16- Designed for both testing and runtime scenarios.
17- Match request by method, URL params, headers and bodies.
18- Extensible and pluggable HTTP matching rules.
19- Ability to switch between mock and real networking modes.
20- Ability to filter/map HTTP requests for accurate mock matching.
21- Supports map and filters to handle mocks easily.
22- Wide compatible HTTP interceptor using `http.RoundTripper` interface.
23- Works with any `net/http` compatible client, such as [gentleman](https://github.com/h2non/gentleman).
24- Network delay simulation (beta).
25- Extensible and hackable API.
26- Dependency free.
27
28## Installation
29
30```bash
31go get -u gopkg.in/h2non/gock.v1
32```
33
34## API
35
36See [godoc reference](https://godoc.org/github.com/h2non/gock) for detailed API documentation.
37
38## How it mocks
39
401. Intercepts any HTTP outgoing request via `http.DefaultTransport` or custom `http.Transport` used by any `http.Client`.
412. Matches outgoing HTTP requests against a pool of defined HTTP mock expectations in FIFO declaration order.
423. If at least one mock matches, it will be used in order to compose the mock HTTP response.
434. If no mock can be matched, it will resolve the request with an error, unless real networking mode is enable, in which case a real HTTP request will be performed.
44
45## Tips
46
47#### Testing
48
49Declare your mocks before you start declaring the concrete test logic:
50
51```go
52func TestFoo(t *testing.T) {
53  defer gock.Off() // Flush pending mocks after test execution
54
55  gock.New("http://server.com").
56    Get("/bar").
57    Reply(200).
58    JSON(map[string]string{"foo": "bar"})
59
60  // Your test code starts here...
61}
62```
63
64#### Race conditions
65
66If you're running concurrent code, be aware that your mocks are declared first to avoid unexpected
67race conditions while configuring `gock` or intercepting custom HTTP clients.
68
69`gock` is not fully thread-safe, but sensible parts are. Any help making `gock` more reliable in this sense is highly appreciated.
70
71#### Define complex mocks first
72
73If you're mocking a bunch of mocks in the same test suite, it's recommended to define the more
74concrete mocks first, and then the generic ones.
75
76This approach usually avoids matching unexpected generic mocks (e.g: specific header, body payload...) instead of the generic ones that performs less complex matches.
77
78## Examples
79
80See [examples](https://github.com/h2non/gock/tree/master/_examples) directory for more featured use cases.
81
82#### Simple mocking via tests
83
84```go
85package test
86
87import (
88  "github.com/nbio/st"
89  "gopkg.in/h2non/gock.v1"
90  "io/ioutil"
91  "net/http"
92  "testing"
93)
94
95func TestSimple(t *testing.T) {
96  defer gock.Off()
97
98  gock.New("http://foo.com").
99    Get("/bar").
100    Reply(200).
101    JSON(map[string]string{"foo": "bar"})
102
103  res, err := http.Get("http://foo.com/bar")
104  st.Expect(t, err, nil)
105  st.Expect(t, res.StatusCode, 200)
106
107  body, _ := ioutil.ReadAll(res.Body)
108  st.Expect(t, string(body)[:13], `{"foo":"bar"}`)
109
110  // Verify that we don't have pending mocks
111  st.Expect(t, gock.IsDone(), true)
112}
113```
114
115#### Request headers matching
116
117```go
118package test
119
120import (
121  "github.com/nbio/st"
122  "gopkg.in/h2non/gock.v1"
123  "io/ioutil"
124  "net/http"
125  "testing"
126)
127
128func TestMatchHeaders(t *testing.T) {
129  defer gock.Off()
130
131  gock.New("http://foo.com").
132    MatchHeader("Authorization", "^foo bar$").
133    MatchHeader("API", "1.[0-9]+").
134    HeaderPresent("Accept").
135    Reply(200).
136    BodyString("foo foo")
137
138  req, err := http.NewRequest("GET", "http://foo.com", nil)
139  req.Header.Set("Authorization", "foo bar")
140  req.Header.Set("API", "1.0")
141  req.Header.Set("Accept", "text/plain")
142
143  res, err := (&http.Client{}).Do(req)
144  st.Expect(t, err, nil)
145  st.Expect(t, res.StatusCode, 200)
146  body, _ := ioutil.ReadAll(res.Body)
147  st.Expect(t, string(body), "foo foo")
148
149  // Verify that we don't have pending mocks
150  st.Expect(t, gock.IsDone(), true)
151}
152```
153
154#### JSON body matching and response
155
156```go
157package test
158
159import (
160  "bytes"
161  "github.com/nbio/st"
162  "gopkg.in/h2non/gock.v1"
163  "io/ioutil"
164  "net/http"
165  "testing"
166)
167
168func TestMockSimple(t *testing.T) {
169  defer gock.Off()
170
171  gock.New("http://foo.com").
172    Post("/bar").
173    MatchType("json").
174    JSON(map[string]string{"foo": "bar"}).
175    Reply(201).
176    JSON(map[string]string{"bar": "foo"})
177
178  body := bytes.NewBuffer([]byte(`{"foo":"bar"}`))
179  res, err := http.Post("http://foo.com/bar", "application/json", body)
180  st.Expect(t, err, nil)
181  st.Expect(t, res.StatusCode, 201)
182
183  resBody, _ := ioutil.ReadAll(res.Body)
184  st.Expect(t, string(resBody)[:13], `{"bar":"foo"}`)
185
186  // Verify that we don't have pending mocks
187  st.Expect(t, gock.IsDone(), true)
188}
189```
190
191#### Mocking a custom http.Client and http.RoundTripper
192
193```go
194package test
195
196import (
197  "github.com/nbio/st"
198  "gopkg.in/h2non/gock.v1"
199  "io/ioutil"
200  "net/http"
201  "testing"
202)
203
204func TestClient(t *testing.T) {
205  defer gock.Off()
206
207  gock.New("http://foo.com").
208    Reply(200).
209    BodyString("foo foo")
210
211  req, err := http.NewRequest("GET", "http://foo.com", nil)
212  client := &http.Client{Transport: &http.Transport{}}
213  gock.InterceptClient(client)
214
215  res, err := client.Do(req)
216  st.Expect(t, err, nil)
217  st.Expect(t, res.StatusCode, 200)
218  body, _ := ioutil.ReadAll(res.Body)
219  st.Expect(t, string(body), "foo foo")
220
221  // Verify that we don't have pending mocks
222  st.Expect(t, gock.IsDone(), true)
223}
224```
225
226#### Enable real networking
227
228```go
229package main
230
231import (
232  "fmt"
233  "gopkg.in/h2non/gock.v1"
234  "io/ioutil"
235  "net/http"
236)
237
238func main() {
239  defer gock.Off()
240  defer gock.DisableNetworking()
241
242  gock.EnableNetworking()
243  gock.New("http://httpbin.org").
244    Get("/get").
245    Reply(201).
246    SetHeader("Server", "gock")
247
248  res, err := http.Get("http://httpbin.org/get")
249  if err != nil {
250    fmt.Errorf("Error: %s", err)
251  }
252
253  // The response status comes from the mock
254  fmt.Printf("Status: %d\n", res.StatusCode)
255  // The server header comes from mock as well
256  fmt.Printf("Server header: %s\n", res.Header.Get("Server"))
257  // Response body is the original
258  body, _ := ioutil.ReadAll(res.Body)
259  fmt.Printf("Body: %s", string(body))
260
261  // Verify that we don't have pending mocks
262  st.Expect(t, gock.IsDone(), true)
263}
264```
265
266## Hacking it!
267
268You can easily hack `gock` defining custom matcher functions with own matching rules.
269
270See [add matcher functions](https://github.com/h2non/gock/blob/master/_examples/add_matchers/matchers.go) and [custom matching layer](https://github.com/h2non/gock/blob/master/_examples/custom_matcher/matcher.go) examples for further details.
271
272## License
273
274MIT - Tomas Aparicio
275