India’s longest ropeway on the Brahmaputra river, Guwahati

Design Virtual Service using Node.js and Mountebank

Timus

--

We will design a flexible virtual service using Node.js and Mountebank that will listen to a specific port for REST requests in HTTP and reuse across all projects

Prerequisites:

  1. Version 8.10.0 or higher of Node.js installed on the machine
  2. GitBash installed on the system
  3. Editor Atom or VSCode installed on the system
  4. Installed Talend API Tester on browser

Step 1 — Initial Setup

Create a folder-MBDemo. Open GitBash on MBDemo folder and type

npm init

follow the onscreen instruction

Now type atom . it will open the project in atom editior as follows

Create a folder src and then index.js

Now install the Mountebank npm package using the following command and wait for MB to install

npm install -save mountebank

Now, update in package.json as highlight below.

Step 2: Setting file

In this step, we will create a settings file that determines which port the Mountebank instance and the mock services will listen to. Create a settings.js under the src folder

Add the following code in settings.js

module.exports = {
port: 6000,
hello_service_port: 6001,
}

This settings file has two entries: port: 6000 assigns port 6000 to the main Mountebank instance, hello_service_port: 6001 assigns port 6001 to the Hello World test service.

Step 3 — Building the Initialization Script

In this step, we are going to add code on index.js that starts an instance of Mountebank. The index.js will be the entry point of the application, i.e., when you run the app, this script will run first.

Add the following code to the index.js file:

const mb = require('mountebank');
const settings = require('./settings');

const mbServerInstance = mb.create({
port: settings.port,
pidfile: '../mb.pid',
logfile: '../mb.log',
protofile: '../protofile.json',
ipWhitelist: ['*']
});
  1. It imports the Mountebank npm package that you installed earlier (const mb = require('mountebank');).

2. It imports the settings module you created in the previous step (const settings = require('./settings');).

3. It creates an instance of the Mountebank server with mb.create().

The server will listen at the port specified in the settings file.

The pidfile, logfile, and protofile parameters are for files that Mountebank uses internally to record its process ID, specify where it keeps its logs, and set a file to load custom protocol implementations.

The ipWhitelist setting specifies what IP addresses are allowed to communicate with the Mountebank server. In this case, we’re opening it up to any IP address.

Step 4 — Building a Mountebank Client

Mountebank communicates using a REST API. In this step, we will create an intermediate MB Client which will forward the service request or imposter to the MB Instance which is listening on port 6000 using HTTP post request.

An imposter is a name for a mock service in Mountebank. Imposters can be simple or complex, depending on the behaviors you want in your mock.

Begin by installing the node-fetch library:

npm install -save node-fetch

The node-fetchlibrary gives us an implementation of the JavaScript Fetch API, which we can use to write shorter HTTP requests.

Create a file called mountebank-helper.js:

To set up the client, add the following code in the file mountebank-helper.js:

const fetch = require('node-fetch');
const settings = require('./settings');

function postImposter(body) {
const url = `http://127.0.0.1:${settings.port}/imposters`;

return fetch(url, {
method:'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body)
});
}

module.exports = { postImposter };

This code starts by pulling in the node-fetch library and your settings file. This module then exposes a function called postImposter that posts service mocks to Mountebank. Next, body: determines that the function takes JSON.stringify(body), a JavaScript object. This object is what you’re going to POST to the Mountebank service. Since this method is running locally, you run your request against 127.0.0.1 (localhost). The fetch method takes the object sent in the parameters and sends the POST request to the url.

Step 5 — Creating Your First Mock Service

In previous steps, we have designed an application that creates a Mountebank server and code to call that server. Now it’s time to use that code to build an imposter or a mock service.

In Mountebank, each imposter contains stubs. Stubs are configuration sets that determine the response that an imposter will give. Stubs can be further divided into combinations of predicates and responses. A predicate is the rule that triggers the imposter’s response. Predicates can use lots of different types of information, including URLs, request content (using XML or JSON), and HTTP methods.

Create a file called hello-service.js.This file will contain the definition of your mock service. Then add the following code:

const mbHelper = require('./mountebank-helper');
const settings = require('./settings');

function addService() {
const response = { message: "hello world" }

const stubs = [
{
predicates: [ {
equals: {
method: "GET",
"path": "/"
}
}],
responses: [
{
is: {
statusCode: 200,
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(response)
}
}
]
}
];

const imposter = {
port: settings.hello_service_port,
protocol: 'http',
stubs: stubs
};

return mbHelper.postImposter(imposter);
}

module.exports = { addService };

This code defines an imposter with a single stub that contains a predicate and a response. Then it sends that object to the Mountebank server. This code will add a new mock service that listens for GET requests to the root url and returns { message: "hello world" } when it gets one.

Let’s take a look at the addService() function, it defines a stub. This stub has two parts. The predicate part is looking for a GET request to the root (/) URL. This means that stubs will return the response when someone sends a GET request to the root URL of the mock service. The second part of the stub is the responses array. In this case, there is one response, which returns a JSON result with an HTTP status code of 200.

The final step defines an imposter that contains that stub:

...
const imposter = {
port: settings.hello_service_port,
protocol: 'http',
stubs: stubs
};
...

This is the object you’re going to send to the /imposters the endpoint to create an imposter that mocks a service with a single endpoint. The preceding code defines your imposter by setting the port to the port you determined in the settings file, setting the protocol to HTTP, and assigning stubs as the imposter’s stubs.

Now that you have a mock service, the code sends it to the Mountebank server:

...
return mbHelper.postImposter(imposter);
...

As mentioned before, Mountebank uses a REST API to manage its objects. The preceding code uses the postImposter() function that you defined earlier to send a POST request to the server to activate the service.

Next, call the newly created addService() function in index.js.

To make sure that the function is called when the Mountebank instance is created, add the following highlighted lines:

const mb = require('mountebank');
const settings = require('./settings');
const helloService = require('./hello-service');
const mbServerInstance = mb.create({
port: settings.port,
pidfile: '../mb.pid',
logfile: '../mb.log',
protofile: '../protofile.json',
ipWhitelist: ['*']
});
mbServerInstance.then(function() {
helloService.addService();
}
);

When a Mountebank instance is created, it returns a promise the .then(function(){...}) the function executes when the promise resolves.

To start the mock service is created to run the command:

npm test

To test, send an HTTP get request at HTTP://127.0.0.1:6001/ from Talend API Tester, we will get a response “hello world”.

Summary:

  1. Index.js code will run first, it will create an initiate of MB, running at port 6000 which is defined at settings.js, and finally, call helloService.addService()
  2. Now from hello-service.js, the function addService() will create an imposter by defining the stub. To create an imposter, it uses the function of postImposter mountebank-helper.js.
  3. In mountebank-helper.js, it sends the HTTP post of the imposter to the MB which is listening on port 6000.
  4. Finally, the imposter is ready and listening on port 6001.

You can download the code from here

You can refer to the earlier post: Virtual Service creation from Scratch-MounteBank Part-01

As always, if you get stuck, ask for help.

Similarly, if you are looking to create XPath, Script, and Analysis of the existing automation scripts instantly you can use the web extension tool TruePath.

About author Sumit: QA for 15 years and passionate about Test Automation, Service Virtualization, Web service, DevOps & ETL-BI Testing. Currently working for a leading telecom company CenturyLink as an offshore Automation COE lead. Please connect with him on LinkedIn.

--

--