DEV Community

Cover image for Mock back-end for UI testing (Angular)
b0r
b0r

Posted on • Updated on • Originally published at allthingsangular.com

Mock back-end for UI testing (Angular)

Original post with additional details available at: https://allthingsangular.com/angular-and-wiremock-integration-for-ui-testing/

This post describes how to integrate Angular and WireMock (a mock HTTP back-end server). Protractor, along side Jasmine is used to create User Interface (UI) tests. At the same time, Protractor provides integration point between Angular and WireMock.

Table of Content

  • Integrating Angular and WireMock (via Protractor)
  • Using Angular and WireMock (via Protractor)
  • Conclusion

Integrating Angular and WireMock (via Protractor)

WireMock is started as a standalone instance and is used as a HTTP mock server. Protractor is configured to automatically start WireMock instance before executing tests. Protractor is also configured to stop WireMock instance after all tests are executed.

Integration process is demonstrated on a newly created Angular application.

Create a demo project

  • Create a new Angular application using Angular CLI
$ ng new wiremock-demo
Enter fullscreen mode Exit fullscreen mode

Download WireMock

  • Under wiremock-demo/e2e create a new wiremock-config folder
$ mkdir wiremock-config
Enter fullscreen mode Exit fullscreen mode
  • Download WireMock standalone under wiremock-demo/e2e/wiremock-config/
$ curl https://repo1.maven.org/maven2/com/github/tomakehurst/wiremock-standalone/2.27.2/wiremock-standalone-2.27.2.jar --output wiremock-standalone.jar
Enter fullscreen mode Exit fullscreen mode
  • Check that wiremock-standalone.jar can be started
$ java -jar wiremock-standalone.jar --port 9000
Enter fullscreen mode Exit fullscreen mode
  • Check that you can access the server from the new terminal window or a browser
$ curl localhost:9000/api
Enter fullscreen mode Exit fullscreen mode
  • If everything is OK you should see the following message
No response could be served as there are no stub mappings in this WireMock instance.
Enter fullscreen mode Exit fullscreen mode
  • Stop WireMock standalone by pressing Control + c

Configure WireMock to serve predefined responses

WireMock can be configured to serve predefined responses via

  • JSON over HTTP
  • JSON configuration file

In this example, JSON configuration file is used.

When started, WireMock server creates two folders under the current one (e.g. wiremock-demo/e2e/wiremock-config), mappings and __files. Folders are only created if they don’t already exist and won’t be deleted when the WireMock instance is stopped.

To serve predefined response and validate they are working fine:

  • Create a new hello-world.json file under mappings folder
  • Add following content to hello-world.json file
{
    "request": {
        "method": "GET",
        "url": "/api/hello-world"
    },
    "response": {
        "status": 200,
        "body": "Hello World!"
    }
}
Enter fullscreen mode Exit fullscreen mode
  • Start previously stopped instance of WireMock standalone server
$ java -jar wiremock-standalone.jar --port 9000
Enter fullscreen mode Exit fullscreen mode
  • Validate that configured response is served
$ curl localhost:9000/api/hello-world
Enter fullscreen mode Exit fullscreen mode
  • If everything is OK you should see the following message json Hello World!

Configure Protractor to start WireMock before executing tests

Protractor provides a lot of configuration options. One of them is a beforeLaunch() callback function. It is executed only once, before tests are started. It’s main purpose is to bring up test dependencies.

To start WireMock standalone before tests are executed, update protractor.conf.js with following content

  • Import function for spawning a new process
const { spawn } = require('child_process')
Enter fullscreen mode Exit fullscreen mode
  • Start a WireMock standalone before executing tests
beforeLaunch: async function () {
    // spawns a new process 
    spawn(
      // the command to run
      'java',
      // list of string arguments
      ['-jar', './e2e/wiremock-config/wiremock-standalone.jar', '--port=9000'],
      // options is used to configure the pipes that are established between the parent and child process.
      { stdio: ['pipe', 'inherit', 'inherit']}
    );
Enter fullscreen mode Exit fullscreen mode
  • Additional check is needed to confirm WireMock server is ready to serve responses. Updated beforeLaunch() with following content (add after spawning a new WireMock process)
for (let i = 0; i < 5; i++) {
      try {
        const response = await fetch('http://localhost:9000/__admin/mappings')
        if (response.ok) {
          const data = await response.json();
          console.log("mappings: ", data)
          break;
        } else {
          throw new HTTPResponseError(response);
        }
      } catch (error) {
        console.log(error);
        await delay(1000)
      }
    }
Enter fullscreen mode Exit fullscreen mode
  • Add node-fetch as a dependency
npm i node-fetch --save
Enter fullscreen mode Exit fullscreen mode
  • Import fetch
const fetch = require("node-fetch");
Enter fullscreen mode Exit fullscreen mode
  • Introduce a delay by adding following function to the end of the protractor.conf.js
const delay = ms => new Promise(res => setTimeout(res, ms));
Enter fullscreen mode Exit fullscreen mode

Configure Protractor to stop WireMock after executing tests

Protractor provides another callback function afterLaunch() which is called only once, before the program exits. It is called after all tests have finished running and the WebDriver instance has been shut down.

Update protractor.conf.js to shut down WireMock standalone instance after tests are executed.

  • Import function for synchronously spawning a new process
const { spawnSync } = require('child_process')
Enter fullscreen mode Exit fullscreen mode
  • Stop WireMock standalone after tests are done and WebDriver is closed
afterLaunch: function () {
    // spawns a new synchronous process
    // the function will not return until the child process has been fully closed
    spawnSync('sh', ['-c', 'lsof -t -i :9000 | xargs kill -9'])
  }
Enter fullscreen mode Exit fullscreen mode

Using Angular and WireMock (via Protractor)

Once WireMock is up and running, point you service to it (instead of the real back-end previously used).

Potential problems

  • Cross-Origin Request Blocked which you can fix by adding --enable-stub-cors flag when starting WireMock. It enables automatic sending of cross-origin response headers.

Conclusion

Testing at different levels is of crucial importance for the project success. It provides assurance that the application is working correctly and brings promised value. WireMock provides an excellent HTTP mock server that can be useful in integration and/or E2E tests.

Sources

Top comments (0)