A modern mock server. A mock server is designed to stand in for other services when performing integration test. It should be able to return all kinds of canned responses for success, failure and edge cases. A modern mock server should be lightweight, easily configurable, and highly scalable. In looking at the field of mock servers already available, none of them seem very modern, being built on heavy weight technologies, requiring a stiff learning curve to get a simple test case running.
empholite is relatively stateless. You can spin up and configure as needed. It has a UI and will have a REST API for describing call and response patterns. SDETs can build up patterns interactively and then use them as part of exploratory testing. Or test runners can make simple REST calls to set needed response patterns, individual or in bulk, as part of test setup and tear down. empholite is able to mock multiple services so that tests can focus on the service under test more easily instead of compounding the costs, in effort and resources, of providing a live test service ecosystem or even multiple mock servers for each replaced live service.
empholite has an endpoint that responds to any call with a path starting with /api
. empholite looks up applicable recipes based on the full path and on the requested host. You may use host headers or host aliasing, both will work. All rules for a matching path will be tried in order from the most specific to the least specific. Specificity is based right now on the number of rules--more rules means more specific. Each rule is tested, if all rules pass, then the associated payload for the recipe is served.
A recipe has an endpoint, which is a full url including scheme and hostname so that matches can be done based on host aliasing. For instance, http://foo.com/api/foo
and http://bar.com/api/foo
are distinct; even though they have the same patch, only calls to foo.com
will match the recipe including that hostname in the specified endpoint. A recipe may have zero or more rules. Rules are evaluated against the request, if a rule fails, evaluation halts and empholite tries the next recipe that for the given endpoint, if there is one, or if no recipes match based on the evaluated rules, a 404 is returned. Recipes include a payload which right now are literal JSON.
- Authenticated call - In order for this rule to match, it expects an "Authorization" header whose value is "Bearer ". You must specific a public key for this rule. If
KEY_PATH_KIND
is "file" thenKEY_PATH
must be the location to a JSON file and the rule must have a valid property path, for examplepublic.auth.001
, to a PEM encoded string value of the key. IfKEY_PATH_KIND
is "directory" thenKEY_PATH
must be a directory and the rule must have a value that is a relative path from this directory to a PEM encoded public key file. The public key is used to verify the signature on the JWT. - Subject - In order for this rule to match, it expects an "Authorization" header, just like the authenticated call rule. The rule must have a subject value and will only match if the decoded JWT from the auth header contains a "subject" claim that matches the rule's subject value.
Empholite supports a REST API to make it easier to utilize as part of test automation.
- Add REST API
- Add the ability to proxy between two live services, recording calls and responses which can be copied and edited to create new recipes.
- Add ability to use arbitrary response status codes in a recipe.
- Add a rule to match arbitrary headers.
- Add support for path parameters.
- Add support for variable replacement in the payload, for instance to use a path parameter as a value.
- Add other content types for payloads.
- Improve the mock endpoint; use a middleware instead so any path may be used.
If you do not have the Rust toolchain, install by running the following in your terminal:
$ curl https://sh.rustup.rs -sSf | sh
Windows users: follow the link to the rustup project for installation options.
You will need wasm-pack
and rollup
to build and bundle the client.
$ cargo install wasm-pack
$ npm i -g rollup
empholite requires a backing database and currently only supports postgres. You can run postgres natively or use the official Docker image. Once you have a running database server, use createuser
to create a user to own the empholite database, then use createdb
to create a database named empholite
. Set DATABASE_URL to something like postgres://user:password@localhost:5432/empholite
then from the root of the project, to set up the database run
$ cargo install --no-default-features diesel_cli --features postgres
$ diesel migration run
empholite can be configured with a few environment variables.
DATABASE_URL
- This is required and of the formpostgres://user:password@localhost:5432/empholite
.KEY_PATH
- This is optional and used with the JWT verification rule. This may point to a directory or a file. SeeKEY_PATH_KIND
andKEY_REF
for more.KEY_PATH_KIND
- Set this to either "file" or "directory", defaults to "directory".HOST
- Optional, defaults to "0.0.0.0".PORT
- Optional, defaults to "8989".STATIC_PATH
- Optional, path to static assets required by the client. Defaults to the expected path in a local working copy of the git repo. Provided in case you create your own Docker image.CLIENT_PATH
- Optional, path to client bundle and associated files. Defaults to the expected path in a local working copy of the git repo. Provided in case you create your own Docker image.
You need to build the client bundle before running.
$ make client/pkg/bundle.js
This rule will use wasm-pack
to build the client Rust code as a WebAssembly library then use rollup
to create a bundle that can be loaded in the browser.
$ cargo run -p empholite
This will run the server which will serve the static assets and the client bundle out of the local working copy. The server listens on port 8989 by default so you can access it at http://localhost:8989.
You can pull the image, cmdln/empholite
. The image contains the binary for the server, the client bundle, and all static assets. All configuration except DATABASE_URL
are set based on the contents of the image.
Topaz Crystal by Joshua Nichol from the Noun Project