Are you looking for a way to mock api calls for your Angular app? Do you want to test different responses locally? Here is ng-apimock! In this post we are going to setup api mocking in a very simple app so you can see what is going on.

The complete code can be found on github here.

Setup

Ng-apimock is a node module for scenario based api mocking. We can include this dependency for development like so.

npm install -D ng-apimock

We need some more dev dependencies that will used later on.

npm install -D concurrently cors express

For example we want to run the mocks and our app at the same time with the following script.

"scripts": {
    ...
    "serve.mock": "concurrently --kill-others \"ng serve --proxy- 
        config src/mock/proxy.config.json\" \"node src/mock/serve- 
        mockdata.js\"",
    ...
  },

Here we refer to a proxy configuration located at src/mock/proxy.config.json. We opt out of the security and rewrite the api path to point to our mock server.

{
    "/api/*": {
        "target": "http://localhost:3000",
        "secure": false,
        "changeOrigin": true,
        "logLevel": "info",
        "pathRewrite": {
            "^/api": "http://localhost:3000/ngapimock"
          }
    }
}

Note that this proxy config is not specific to ng-apimock. It can be used in all sorts of situations, for example in a local setup in combination with a Spring Boot api.

Concurrently we start our mock server. The config is found in src/mock/serve-mockdata.js. Here we see that the cors and express dependencies are used. Moreover we define the port and url where we can navigate to the mock server: http://localhost:3000/mocking/. Finally we point out where the mock scenario’s can be found.

'use strict';

const ngApimock= require('ng-apimock')();
const express = require('express');
const cors = require('cors');
const app = express();
const ngApimockRequest = require('ng-apimock/lib/utils').ngApimockRequest;

const CONFIG = {
    ngApiMock: {
        port: 3000,
        appPath: 'build/ng-apimock',
        url: '/mocking',
        mockFilesPath: 'e2e/mocks'
    }
}

ngApimock.run({
    'src': CONFIG.ngApiMock.mockFilesPath,
    'outputDir': CONFIG.ngApiMock.appPath,
    'done': function() {
    }
});

ngApimock.watch(CONFIG.ngApiMock.mockFilesPath);
app.use(ngApimockRequest);
app.use(CONFIG.ngApiMock.url, express.static(CONFIG.ngApiMock.appPath));
app.use(cors());
app.listen(3000, 'localhost');

With this in place we can run our command and see that both the app and the mock server are started.

Screenshot 2020 01 02 at 16.02.55 - NG-APIMOCK

Mock your service

With the setup done we can move on and define what the mock should do. Our service does the following http call.

this.status$ = this.httpClient.get('/api/status').pipe(
    map((response) => response[0].message)
);

To summarise it does a GET on the path /api/status and tries to read the message of the first element. Our mock can be configured to return this.

{
    "expression": "/status",
    "method": "GET",
    "name": "getStatus",
    "isArray": true,
    "responses": {
      "status OK": {
        "default": true,
        "status": 200,
        "data": [{
            "message": "OK"
        }]
      },
      "status Unauthorized": {
        "status": 401,
        "data": {}
      }
   }
}

We define on which calls it should react. Remember we did a rewrite on /api to our mock server. In the responses section we define the different scenario’s we want to have. Here we have the status OK response and the status Unauthorized response.

When we run our serve.mock script we can choose which scenario to use when we navigate to http://localhost:3000/mocking/.

Screenshot 2020 01 02 at 15.29.14 - NG-APIMOCK

When we use the app we see that it reacts accordingly.

Screenshot 2020 01 02 at 16.13.00 - NG-APIMOCK

Hopefully you can now define your own mocks enabling you to develop Angular apps locally with super speed. Happy mocking!