Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/mkeeler/mock-http-api
Go helpers for mocking an HTTP API using stretchr/testify/mock
https://github.com/mkeeler/mock-http-api
Last synced: 19 days ago
JSON representation
Go helpers for mocking an HTTP API using stretchr/testify/mock
- Host: GitHub
- URL: https://github.com/mkeeler/mock-http-api
- Owner: mkeeler
- License: mpl-2.0
- Created: 2020-09-09T20:20:20.000Z (about 4 years ago)
- Default Branch: master
- Last Pushed: 2020-12-03T16:21:42.000Z (almost 4 years ago)
- Last Synced: 2024-10-13T01:06:28.487Z (about 1 month ago)
- Language: Go
- Size: 37.1 KB
- Stars: 3
- Watchers: 1
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# mock-http-api [![PkgGoDev](https://pkg.go.dev/badge/github.com/mkeeler/mock-http-api)](https://pkg.go.dev/github.com/mkeeler/mock-http-api)
Go helpers for mocking an HTTP API using stretchr/testify/mock## Library Usage
```go
package mock_testimport (
"encoding/json"
"net/http"
"testing"
mockapi "github.com/mkeeler/mock-http-api"
)// This test will pass as all the requisite API calls are made.
func TestMyAPI(t *testing.T) {
m := mockapi.NewMockAPI(t)// http.Get will add both of the headers but we don't want to care about them.
m.SetFilteredHeaders([]string{
"Accept-Encoding",
"User-Agent",
})
// This sets up an expectation that a GET request to /my/endpoint will be made and that it should
// return a 200 status code with the provided map sent back JSON encoded as the body of the response
call := m.WithJSONReply(mockapi.NewMockRequest("GET", "/my/endpoint"), 200, map[string]string{
"foo": "bar",
})
// This sets the call to be required to happen exactly once
call.Once()
// This makes the HTTP request to the mock HTTP server. The mock api server exposes a URL()
// method which will return a string of the form http://: that you can use to make requests.
// Typically this bit of code below would be replaced with invocation of some function that uses
// your API
resp, err := http.Get(fmt.Sprintf("%s/my/endpoint", m.URL()))
if err != nil {
t.Fatalf("Error issuing GET of /my/endpoint: %v", err)
}defer resp.Body.Close()
dec := json.NewDecoder(resp.Body)var output map[string]string
if err := dec.Decode(&output); err != nil {
t.Fatalf("Error decoding response: %v", err)
}
if val, ok := output["foo"]; !ok || val != "bar" {
t.Fatalf("Didn't get the expected response")
}
}
```## Code Generation
The code generator will create a new mock API type with helper methods for all the desired endpoints. These helpers
are meant to be more ergonomic to use that the raw `mock-http-api` module itself.### Installing the code generator
```sh
go get github.com/mkeeler/mock-http-api/cmd/mock-api-gen
```_Note that you may need to run this command with GO111MODULE=on if executing outside of your GOPATH_
### Using `mock-api-gen`
```sh
mock-api-gen -type MockMyAPI -endpoints ./endpoints.json -pkg myapi -output api.helpers.go
```This command will take in the JSON file of endpoints and generate the desired type with helpers for mocking responses to each API. See [endpoint options](#endpoint-options) to view the list of available options to configure mocked endpoints.
The format of the endpoints file is:
```json
{
"Endpoints": {
"UpdateResource": {
"Method": "POST",
"Path": "/resource/%s",
"PathParameters": ["resourceID"],
"BodyFormat": "json",
"ResponseFormat": "json",
"Headers": true,
"QueryParams": false
}
}
}
```Using this as input the following file would be generated:
```go
// Code generated by "mock-expect-gen -type MockAPI -pkg fakeapi -endpoints endpoints.json -output ./api.go"; DO NOT EDIT.package fakeapi
import (
"fmt"
mockapi "github.com/mkeeler/mock-http-api"
)type MockAPI struct {
*mockapi.MockAPI
}func NewMockAPI(t mockapi.TestingT) *MockAPI {
return &MockAPI{
MockAPI: mockapi.NewMockAPI(t),
}
}func (m *MockConsulAPI) UpdateResource(resourceID string, headers map[string]string, body map[string]interface{}, status int, reply interface{}) *mockapi.MockAPICall {
req := mockapi.NewMockRequest("POST", fmt.Sprintf("/resource/%s", resourceID)).WithBody(body).WithHeaders(headers)return m.WithJSONReply(req, status, reply)
}
```Then when you want to use this you would:
```go
func TestFakeAPI(t *testing.T) {
m := fakeapi.NewMockAPI(t)
// Not necessary when the `t` passed into NewMockAPI supports a Cleanup method. (such as with the Go 1.14 testing.T type)
defer m.Close()
m.UpdateResource("some-id-here",
nil,
map[string]interface{"abc", "def"},
200,
map[string]interface{"abc", "def", "added": true})
httpServerURL := m.URL()
// do something to cause the HTTP API call to happen here.
// nothing else is necessary. Either the deferred m.Close or the automatic testing cleanup
// will assert that the required API calls were made.
}
```#### Endpoint Options
Endpoint options for generating method signatures:| Argument | Type | Description |
| - | - | - |
| Method | `string` | The HTTP method for the endpoint. |
| Path | `string` | The path of the endpoint. Include string format verbs to represent path parameters (`/v1/resource/%s`).
| PathParameters | `[]string` | List of path parameters of the endpoint. |
| BodyFormat | `string` | The format of the body expected for the HTTP request. For example, none, json, string, stream. |
| BodyType | `string` | A string describing the go type for the method signature to include the typed representation of the request body. The default type is `map[string]interface{}`. Custom types from other packages, like `*api.Resource`, are supported. This requires the package to be specified in order to be properly imported. See [import options](#import-options) for more information. |
| QueryParams | `bool` | This includes the option for mocking API query params in the method signature with the type `map[string]string`. |
| Headers | `bool` | This includes the option for HTTP headers for the request in the method signature with the type `map[string]string`. |
| ResponseFormat | `string` | The format of the response body returned: none, json, string, stream, func. |
| ResponseType | `string` | A string describing the go type for the method signature to include the typed representation of the response body. The default type is `interface{}`. Custom types from other packages, like `*api.Resource`, are supported. This requires the package to be specified in order to be properly imported. See [import options](#import-options) for more information. |#### Import Options
To include custom types in the method signature for strict type checking, specify the import package in the endpoints file.
```json
{
"Imports": {
"api": "github.com/namespace/project/path/api"
},
"Endpoints": {
"ListResource": {
"Method": "GET",
"Path": "/resources",
"ResponseFormat": "json",
"ResponseType": "[]*api.Resource"
}
}
}
```#### Full Usage
```
Usage of mock-api-gen:
mock-api-gen [flags] -type -endpoints [package]
Flags:
-endpoints string
File holding the endpoint configuration. (default "endpoints")
-output string
Output file name.
-pkg string
Name of the package to generate methods in
-tag value
Build tags the generated file should have. This may be specified multiple times.
-type string
Method receiver type the mock API helpers should be generated for
```