XbyOrange / mocks-server

Mocks server with extensible fixtures groupables in predefined behaviors. Behavior can be changed using CLI or REST API
Apache License 2.0
2 stars 1 forks source link
api behaviors cli development emulation end-to-end-testing express fixtures inquirer interactive-cli mocks rest server simulation testing

Build status Coverage Status Quality Gate

NPM dependencies Last commit Last release

NPM downloads License

Mocks Server

Mocks server with extensible fixtures groupables in predefined behaviors. Behavior can be changed using built-in CLI or REST API.

Table of contents

Getting Started

This package provides a server that simulates API behaviors. As input, it needs "fixtures", which are responses for specific uris, and "features", which are sets of "fixtures".

It also provide a built-in CLI and a REST API which allows to change the currently used "feature" in any moment simply making an http request.

Installation

npm i @xbyorange/mocks-server --save-dev

Usage

Interactive CLI

Add an script to your package.json file, including the path to your mocks folder:

"scripts": {
  "mocks-server" : "mocks-server --features=./mocks"
}

Now, you can start the mocks server CLI simply typing:

npm run mocks-server

cli-home

REST API

The server includes a REST API that allows to change dinamically the current feature, change delay time, etc.

Available api resources are:

Programmatic usage

CLI

The interactive CLI can be instantiated and started programmatically:

const { Cli } = require("@xbyorange/mocks-server");

const startMyCli = () => {
  const cli = new Cli({
    port: 3200,
    log: "debug",
    watch: false
  });

  return cli.start();
};

startMyCli().catch(err => {
  console.log("Error starting CLI", err);
});
Cli ([options][,customQuitMethod])

For first argument options, please read the options chapter of this documentation. Available methods of an instance are:

Server

The server can be instantiated and started programmatically:

const { Server } = require("@xbyorange/mocks-server");

const startMyServer = () => {
  const server = new Server(path.resolve(__dirname, "mocks"), {
    port: 3200,
    log: "debug",
    watch: false
  });

  return server.start();
};

startMyServer().then(server => {
  console.log("Server started", server);
});
Server (featuresFolder [,options])

First argument is mandatory, and has to be a path to a folder containing "features". All files in the folder will be loaded recursively, including subfolders. For second argument options, please read the options chapter of this documentation.

Available methods of an instance are:

Available getters are:

Global usage

The mocks server can be used as a global dependency as well:

npm i @xbyorange/mocks-server -g

Now, you can start the built-in command line interface from anywhere, providing a path to a features folder:

mocks-server --features=./path-to-features

Options

Defining mocks

The Mocks server handles two main concepts for defining mocks:

Features

Each feature consists in a set of "fixtures", which are server responses for specific uris.

Features are extensibles, so, you can have a "base" feature, which defines the standard behavior of the mocks server and responses for all api uris, and change this behavior creating new features that changes only responses for certain "uris". All features are extensible as well.

For creating a Feature, you have to use the mocks-server "Feature" class, providing an array of "fixtures" to it:

// Features file 1

const { Feature } = require("@xbyorange/mocks-server");

const fixtures = require("./fixtures");

const myFeature = new Feature([fixtures.uri_1_fixture, fixtures.uri_2_fixture]);

module.exports = {
  myFeature
};

Now, when loaded, the server will have available a "myFeature" feature, which contains two fixtures. You can add more features extending the first one and changing only the response for "uri_2", for example:

// Features file 2

const { myFeature } = require("./features");

const fixtures = require("./fixtures");

const myFeature2 = myFeature.extend([fixtures.uri_2_different_fixture]);

module.exports = {
  myFeature2
};

Now, server will have available "myFeature" and "myFeature2" features. And "myFeature2" will send a different response only for "uri_2" (supossing that "uri_2_fixture" and "uri_2_different_fixture" were defined with the same uri)

Fixtures

A "fixture" defines the response for an specific uri. It has to be an object containing properties:

// Fixtures file

const uri_1_fixture = {
  url: "/api/foo-uri",
  method: "GET",
  response: {
    status: 200,
    body: [
      {
        name: "foo-name"
      }
    ]
  }
};

const uri_2_fixture = {
  url: "/api/foo-uri-2/:id",
  method: "PUT",
  response: {
    status: 204
  }
};

const uri_2_different_fixture = {
  url: "/api/foo-uri-2/:id",
  method: "PUT",
  response: (req, res) => {
    res.status(404);
    res.send({
      message: `${req.params.id} was not found`
    });
  }
};

module.exports = {
  uri_1_fixture,
  uri_2_fixture,
  uri_2_different_fixture
};

Contributing

Contributors are welcome. Please read the contributing guidelines and code of conduct.