{"id":22207671,"url":"https://github.com/vitorsalgado/mocha","last_synced_at":"2025-07-27T08:32:57.551Z","repository":{"id":37538885,"uuid":"500666099","full_name":"vitorsalgado/mocha","owner":"vitorsalgado","description":"Build Mock APIs in Go","archived":false,"fork":false,"pushed_at":"2023-11-17T00:16:48.000Z","size":1640,"stargazers_count":45,"open_issues_count":13,"forks_count":8,"subscribers_count":3,"default_branch":"3.x","last_synced_at":"2024-08-23T01:06:44.062Z","etag":null,"topics":["go","golang","golang-library","http","mock","mock-server","mocking","stubbing","testing"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/vitorsalgado/mocha/v3","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vitorsalgado.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-06-07T02:45:46.000Z","updated_at":"2024-07-09T14:13:01.000Z","dependencies_parsed_at":"2024-06-18T18:43:10.440Z","dependency_job_id":"564af49a-82d6-4aba-8a0a-80f96ce3b45b","html_url":"https://github.com/vitorsalgado/mocha","commit_stats":{"total_commits":304,"total_committers":5,"mean_commits":60.8,"dds":0.5032894736842105,"last_synced_commit":"f8057256ec693794307c72da5dbb1b19367b4e85"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vitorsalgado%2Fmocha","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vitorsalgado%2Fmocha/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vitorsalgado%2Fmocha/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vitorsalgado%2Fmocha/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vitorsalgado","download_url":"https://codeload.github.com/vitorsalgado/mocha/tar.gz/refs/heads/3.x","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227786833,"owners_count":17819776,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","golang-library","http","mock","mock-server","mocking","stubbing","testing"],"created_at":"2024-12-02T19:14:06.399Z","updated_at":"2024-12-02T19:14:07.459Z","avatar_url":"https://github.com/vitorsalgado.png","language":"Go","readme":"\u003ch1 id=\"mocha-top\" align=\"center\"\u003eMocha\u003c/h1\u003e\n\n\u003cdiv align=\"center\"\u003e\n    \u003ca href=\"#\"\u003e\u003cimg src=\"logo.png\" width=\"120px\" alt=\"Mocha Logo\"\u003e\u003c/a\u003e\n    \u003cp align=\"center\"\u003e\n        HTTP Mocking Tool for Go\n        \u003cbr /\u003e\n    \u003c/p\u003e\n    \u003cdiv\u003e\n      \u003ca href=\"https://github.com/vitorsalgado/mocha/actions/workflows/ci.yml\"\u003e\n        \u003cimg src=\"https://github.com/vitorsalgado/mocha/actions/workflows/ci.yml/badge.svg\" alt=\"CI Status\" /\u003e\n      \u003c/a\u003e\n      \u003ca href=\"https://codecov.io/gh/vitorsalgado/mocha\"\u003e\n        \u003cimg src=\"https://codecov.io/gh/vitorsalgado/mocha/branch/main/graph/badge.svg?token=XOFUV52P31\" alt=\"Coverage\"/\u003e\n      \u003c/a\u003e\n      \u003ca href=\"#\"\u003e\n        \u003cimg alt=\"GitHub go.mod Go version\" src=\"https://img.shields.io/github/go-mod/go-version/vitorsalgado/mocha\"\u003e\n      \u003c/a\u003e\n      \u003ca href=\"https://pkg.go.dev/github.com/vitorsalgado/mocha/v3\"\u003e\n        \u003cimg src=\"https://pkg.go.dev/badge/github.com/vitorsalgado/mocha/v3.svg\" alt=\"Go Reference\"\u003e\n      \u003c/a\u003e\n      \u003ca href=\"https://goreportcard.com/report/github.com/vitorsalgado/mocha/v3\"\u003e\n        \u003cimg src=\"https://goreportcard.com/badge/github.com/vitorsalgado/mocha/v3\" alt=\"Go Report\" /\u003e\n      \u003c/a\u003e\n    \u003c/div\u003e\n\u003c/div\u003e\n\n## Overview\n\nHTTP server mocking tool for Go.  \n**Mocha** creates a real HTTP server and lets you configure response stubs for HTTP Requests when it matches a set of\nmatchers.\nIt provides a functional like API that allows you to match any part of a request against a set of matching\nfunctions that can be composed.\n\nInspired by [WireMock](https://github.com/wiremock/wiremock) and [Nock](https://github.com/nock/nock).\n\n## Installation\n\n```bash\ngo get github.com/vitorsalgado/mocha/v3\n```\n\n## Features\n\n- Configure HTTP response stubs for specific requests based on a criteria set.\n- Matches request URL, headers, queries, body.\n- Stateful matches to create scenarios, mocks for a specific number of calls.\n- Response body template.\n- Response delays.\n- Run in your automated tests.\n\n## How It Works\n\n**Mocha** works by creating a real HTTP Server that you can configure response stubs for HTTP requests when they match a\nset request matchers. Mock definitions are stored in memory in the server and response will continue to be served as\nlong as the requests keep passing the configured matchers.  \nThe basic is workflow for a request is:\n\n- run configured middlewares\n- mocha parses the request body based on:\n  - custom `RequestBodyParser` configured\n  - request content-type\n- mock http handler tries to find a mock for the incoming request were all matchers evaluates to true\n  - if all matchers passes, it will use mock reply implementation to build a response\n  - if no mock is found, **it returns an HTTP Status Code 418 (teapot)**.\n- after serving a mock response, it will run any `PostAction` configured.\n\n## Getting Started\n\nUsage typically looks like the example below:\n\n```go\nfunc Test_Example(t *testing.T) {\n\tm := mocha.New(t)\n\tm.Start()\n\n\tscoped := m.AddMocks(mocha.Get(expect.URLPath(\"/test\")).\n\t\tHeader(\"test\", expect.ToEqual(\"hello\")).\n\t\tQuery(\"filter\", expect.ToEqual(\"all\")).\n\t\tReply(reply.Created().BodyString(\"hello world\")))\n\n\treq, _ := http.NewRequest(http.MethodGet, m.URL()+\"/test?filter=all\", nil)\n\treq.Header.Add(\"test\", \"hello\")\n\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tbody, err := ioutil.ReadAll(res.Body)\n\n\tassert.Nil(t, err)\n\tassert.True(t, scoped.Called())\n\tassert.Equal(t, 201, res.StatusCode)\n\tassert.Equal(t, string(body), \"hello world\")\n}\n```\n\n## Configuration\n\nMocha has two ways to create an instance: `mocha.New()` and `mocha.NewSimple()`.  \n`mocha.NewSimple()` creates a new instance with default values for everything.  \n`mocha.New(t, ...config)` needs a `mocha.T` implementation and allows to configure the mock server.\nYou use `testing.T` implementation. Mocha will use this to log useful information for each request match attempt.\nUse `mocha.Configure()` or provide a `mocha.Config` to configure the mock server.\n\n## Request Matching\n\nMatchers can be applied to any part of a Request and **Mocha** provides a fluent API to make your life easier.  \nSee usage examples below:\n\n### Method and URL\n\n```go\nm := mocha.New(t)\nm.AddMocks(mocha.Request().Method(http.MethodGet).URL(expect.URLPath(\"/test\"))\n```\n\n### Header\n\n```go\nm := mocha.New(t)\nm.AddMocks(mocha.Get(expect.URLPath(\"/test\")).\n    Header(\"test\", expect.ToEqual(\"hello\")))\n```\n\n### Query\n\n```go\nm := mocha.New(t)\nm.AddMocks(mocha.Get(expect.URLPath(\"/test\")).\n    Query(\"filter\", expect.ToEqual(\"all\")))\n```\n\n### Body\n\n**Matching JSON Fields**\n\n```go\nm := mocha.New(t)\nm.AddMocks(mocha.Post(expect.URLPath(\"/test\")).\n    Body(\n        expect.JSONPath(\"name\", expect.ToEqual(\"dev\")), expect.JSONPath(\"ok\", expect.ToEqual(true))).\n    Reply(reply.OK()))\n```\n\n### Form URL Encoded Fields\n\n```go\nm.AddMocks(mocha.Post(expect.URLPath(\"/test\")).\n    FormField(\"field1\", expect.ToEqual(\"dev\")).\n    FormField(\"field2\", expect.ToContain(\"qa\")).\n    Reply(reply.OK()))\n```\n\n## Replies\n\nYou can define a response that should be served once a request is matched.  \n**Mocha** provides several ways to configure a reply.  \nThe built-in reply features are:\n\n- [Basic](#basic-reply)\n- [Random Replies](#random-replies)\n- [Sequence Replies](#replies-in-sequence)\n- [Function](#reply-function)\n- [Reply From Proxied Forwarded Request](#reply-from-forwarded-request)\n- [Specify Headers](#specifying-headers)\n- [Delay Responses](#delay-responses)\n\nReplies are based on the `Reply` interface.  \nIt's also possible to configure response bodies from templates. **Mocha** uses Go Templates.\nReplies usage examples:\n\n### Basic Reply\n\n```go\nm := mocha.New(t)\nm.AddMocks(mocha.Get(expect.URLPath(\"/test\")).\n    Reply(reply.OK())\n```\n\n### Replies In Sequence\n\n```go\nm := mocha.New(t)\nm.AddMocks(mocha.Get(expect.URLPath(\"/test\")).\n    Reply(reply.Seq().\n\t    Add(InternalServerError(), BadRequest(), OK(), NotFound())))\n```\n\n### Random Replies\n\n```go\nm := mocha.New(t)\nm.AddMocks(mocha.Get(expect.URLPath(\"/test\")).\n    Reply(reply.Rand().\n\t\tAdd(reply.BadRequest(), reply.OK(), reply.Created(), reply.InternalServerError())))\n```\n\n### Reply Function\n\n```go\nm := mocha.New(t)\nm.AddMocks(mocha.Get(expect.URLPath(\"/test\")).\n    ReplyFunction(func(r *http.Request, m mocha.M, p params.P) (*mocha.Response, error) {\n        return \u0026mocha.Response{Status: http.StatusAccepted}, nil\n    }))\n```\n\n### Reply From Forwarded Request\n\n**reply.From** will forward the request to the given destination and serve the response from the forwarded server.  \nIt`s possible to add extra headers to the request and the response and also remove unwanted headers.\n\n```go\nm := mocha.New(t)\nm.AddMocks(mocha.Get(expect.URLPath(\"/test\")).\n    Reply(reply.From(\"http://example.org\").\n\t\tProxyHeader(\"x-proxy\", \"proxied\").\n\t\tRemoveProxyHeader(\"x-to-be-removed\").\n\t\tHeader(\"x-res\", \"response\"))\n```\n\n### Body Template\n\n**Mocha** comes with a built-in template parser based on Go Templates.  \nTo serve a response body from a template, follow the example below:\n\n```go\ntemplateFile, _ := os.Open(\"template.tmpl\"))\ncontent, _ := ioutil.ReadAll(templateFile)\n\nm := mocha.New(t)\nm.AddMocks(mocha.Get(expect.URLPath(\"/test\")).\n    Reply(reply.\n        OK().\n        BodyTemplate(reply.NewTextTemplate().\n            FuncMap(template.FuncMap{\"trim\": strings.TrimSpace}).\n            Template(string(content))).\n        Model(data))\n```\n\n### Specifying Headers\n\n```go\nm := mocha.New(t)\nm.AddMocks(mocha.Get(expect.URLPath(\"/test\")).\n    Reply(reply.OK().Header(\"test\", \"test-value\"))\n```\n\n### Delay Responses\n\nYou can configure a delay to responses to simulate timeouts, slow requests and any other timing related scenarios.  \nSee the example below:\n\n```go\ndelay := time.Duration(1250) * time.Millisecond\n\nm.AddMocks(Get(expect.URLPath(\"/test\")).\n    Reply(reply.\n        OK().\n        Delay(delay)))\n```\n\n## Assertions\n\n### Mocha Instance\n\nMocha instance provides methods to assert if associated mocks were called or not, how many times they were called,\nallows you to enable/disable then and so on.  \nThe available assertion methods on mocha instance are:\n\n- AssertCalled: asserts that all associated mocks were called at least once.\n- AssertNotCalled: asserts that associated mocks were **not** called.\n- AssertHits: asserts that the sum of calls is equal to the expected value.\n\n### Scope\n\nMocha instance method `AddMocks` returns a `Scoped` instance that holds all mocks created.  \n`Scopes` allows you control related mocks, enabling/disabling, checking if they were called or not. Scoped instance also\nprovides **assertions** to facility **tests** verification.\nSee below the available test assertions:\n\n- AssertCalled: asserts that all associated mocks were called at least once.\n- AssertNotCalled: asserts that associated mocks were **not** called.\n\n## Matchers\n\nMocha provides several matcher functions to facilitate request matching and verification.\nSee the package `expect` for more details.  \nYou can create custom matchers using these two approaches:\n\n- create a `expect.Matcher` struct\n- use the function `expect.Func` providing a function with the following\n  signature: `func(v any, a expect.Args) (bool, error)`\n\n### Matcher Composition\n\nIt's possible to compose multiple matchers.  \nEvery matcher has a `.And()`, `.Or()` and a `.Xor()` that allows composing multiple matchers.  \nSee the example below:\n\n```go\nexpect.ToEqual(\"test\").And(expect.ToContain(\"t\"))\n```\n\n### BuiltIn Matchers\n\n| Matcher      | Description                                                                                         |\n| ------------ | --------------------------------------------------------------------------------------------------- |\n| AllOf        | Returns true when all given matchers returns true                                                   |\n| AnyOf        | Returns true when any given matchers returns true                                                   |\n| Both         | Returns true when both matchers returns true                                                        |\n| ToContain    | Returns true when expected value is contained on the request value                                  |\n| Either       | Returns true when any matcher returns true                                                          |\n| ToBeEmpty    | Returns true when request value is empty                                                            |\n| ToEqual      | Returns true when values are equal                                                                  |\n| ToEqualFold  | Returns true when string values are equal, ignoring case                                            |\n| ToEqualJSON  | Returns true when the expected struct represents a JSON value                                       |\n| Func         | Wraps a function to create a inline matcher                                                         |\n| ToHaveKey    | Returns true if the JSON key in the given path is present                                           |\n| ToHavePrefix | Returns true if the matcher argument starts with the given prefix                                   |\n| ToHaveSuffix | Returns true when matcher argument ends with the given suffix                                       |\n| JSONPath     | Applies the provided matcher to the JSON field value in the given path                              |\n| ToHaveLen    | Returns true when matcher argument length is equal to the expected value                            |\n| LowerCase    | Lower case matcher string argument before submitting it to provided matcher.                        |\n| UpperCase    | Upper case matcher string argument before submitting it to provided matcher                         |\n| ToMatchExpr  | Returns true then the given regular expression matches matcher argument                             |\n| Not          | Negates the provided matcher                                                                        |\n| Peek         | Will return the result of the given matcher, after executing the provided function                  |\n| ToBePresent  | Checks if matcher argument contains a value that is not nil or the zero value for the argument type |\n| Trim         | Trims' spaces of matcher argument before submitting it to the given matcher                         |\n| URLPath      | Returns true if request URL path is equal to the expected path, ignoring case                       |\n| XOR          | Exclusive \"or\" matcher                                                                              |\n\n---\n\n## Future Plans\n\n- [ ] Configure mocks with JSON/YAML files\n- [ ] CLI\n- [ ] Docker\n- [ ] Proxy and Record\n\n## Contributing\n\nCheck our [Contributing](CONTRIBUTING.md) guide for more details.\n\n## License\n\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fvitorsalgado%2Fmocha.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fvitorsalgado%2Fmocha?ref=badge_shield)\n\nThis project is [MIT Licensed](LICENSE).\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#mocha-top\"\u003eback to the top\u003c/a\u003e\u003c/p\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvitorsalgado%2Fmocha","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvitorsalgado%2Fmocha","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvitorsalgado%2Fmocha/lists"}