Mocking Angular and AngularJS applications

After almost 7 years working for the Rabobank I started my new assignment in February 2017 for the NS (http://www.ns.nl). It’s a real cool assignment where I need to automate their new Angular customer portal.

A not so standard first week

As you may know with a new assignments you need at least a week to get used to everything, read documentation, get credentials, read more documentation, wait for the correct credentials, get to know everybody, still do some more waiting / reading and so on. But this time it was different. Before I went home on the first day I was able to do my first git clone, commit, push and much more.

After attending my first meeting on Tuesday I saw they had an impediment on their backlog concerning “Mocking Angular API calls for local development and E2E-testing”. Because I was not counted in the already running sprint I asked if I could fix the impediment, because I knew a tool that could do that. They agreed, maybe because it was a nice case for them to see what I was capable of ;-).

In this post I’ll explain you which tool I used and and how I’ve implemented it for the new customer portal of the NS.

Reasons for mocking

Before implementing mocking I first needed to know the reasons why I needed to mock the API’s for our Angular application. There were a few reasons:

  1. The frontend developers should be able to develop without having a fully working / functional JAVA API
  2. We should be able to test frontend exceptions that can’t be tested with real API’s
  3. We should be able to test delay’s in API’s and see how the frontend would react on it without adjusting the API’s themselves
  4. Automating tests give the best results on an environment that:
    1. is stable
    2. give the same results back for each API call on each testrun (no data manipulation)

I decided to split the work into two phases. The first phase would hold implementing mocking for frontend development within the current setup. This would also make it possible to fix reason two and three so we can test this manually.

The testautomation would be done in phase 2.

The tool

I was pretty confident about the tool because I had demo of the creator of the tool. The tool is called ng-Apimock, is created by Mischa Dasberg and can be found here.

ng-Apimock is a NPM module that provides the ability to use scenario based API mocking for local development AND for Protractor testing. This means that you, as a developer / tester can already develop (tests) and test your AngularJS or Angular application with all API calls being mocked, even during E2E automation with Protractor. And yes, you are reading it correct, you can even mock your Angular tests you write with Protractor.

But, we can make it even more surreal, you can even run multiple instances of different browsers and still use ng-Apimock with different responses. Isn’t that amazing (hmm, this really sound like a bad Tell Sell commercial).

Lets stop the talking and get to some action.

Phase 1: Implementing ng-Apimock within Angular Seed

The first thing I needed to do is add ng-Apimock in the current NPM-script to start the local environment. Therefore I needed to adjust the project setup which was build with Angular Seed (Angular CLI wasn’t stable when the project started). Angular Seed uses Gulp, which is nice because ng-Apimock also has a gulp plugin called gulp-ng-apimock that also supports Browsersync.

The developers used the NPM-script serve.dev”: “gulp serve.dev –color –env-config dev that would do the following:

"serve.dev": [
    "build.dev",
    "server.start",
    "watch.dev"
]

, see here. This task was also watching the src folder which automatically reloaded the browser when the developers changed HTML / CSS / Javascript.

I won’t be explaining the complete configuration of Angular Seed here, but I needed to adjust the following things:

  1. Start ng-Apimock on the same port Browsersync was serving the development environment on, in this case it was the default http://localhost:5555. This could be done by adjusting the config.ts file, see here,  with this
if (argv.mock) {
    this.PLUGIN_CONFIGS['browser-sync'] = {
        startPath: this.APP_BASE + '#access_token=mockE2E&state=%2Fdashboard&token_type=bearer',
        serveStatic: [{
            route: '/mijnns-mocking',
            dir: `${this.DIST_DIR}/ng-apimock`
        }],
        middleware: [
            require('connect-history-api-fallback')({
                index: `${this.APP_BASE}index.html`
            }),
            (require('ng-apimock/lib/utils').ngApimockRequest)
        ],
        ghostMode: false
    };
}

I added an extra argument to the NPM-script called mock. With yargs I fetch the argument to determine if mocking needs to be used or not. If it is provided the browser-sync plugin is overwritten with the ng-Apimock specific configuration.

  1. Adjust the Environment-configuration that the API’s would go to ng-Apimock, hosted on http://localhost:5555.
  2. Add a new NPM-script called serve.dev.mock that would combine all needed Gulp tasks, including the above 2 steps, to do the mocking trick. It contained
"serve.dev.mock": [
    "build.dev",
    "mock.e2e",
    "server.start",
    "watch.dev"
]

The mock.e2e is a reference to gulp task to load ng-Apimock with this configuration

const ngApimock = require('gulp-ng-apimock');

export = (done: any) => {
    ngApimock.run({
        src: 'e2e-tests/mocking/mocks',
        outputDir: 'dist/ng-apimock',
        done
    });
};

Adjusting the above mentioned parts lead to a new build, see below, that automatically started ng-Apimock in the background.

Scenario based mocking

As mentioned in the Tool block you can use ng-Apimock with scenario’s. This means that a single API can have multiple responses based on a scenario name, see below.

Changing the scenario’s will instantly (after a page reload) give a different response. In this example I change the data from showing a customer who has no cards to a customer who has 1 card.

As said we also needed to test exceptions that could not easily be achieved with real API’s. In this example I changed the scenario to a customer who returned in a 404 error.

We also needed to be able to test an API with a delay. In this example I’ve added a delay of 3 seconds on the API that returns the travels. You will now see a spinner.

Conclusion:

Phase 1 was a success. Our team was able to use ng-Apimock as a mocking framework after 2 weeks of investigating, learning the project setup and mocking all the data.

The second phase, implementing mocking within our testautomation, took some more time. In my next post I’ll explain why it took this much time and how we use it now.

← Previous post

Next post →

2 Comments

  1. Hi there, nice work….

Leave a Reply