How it works...

Our integration tests are very similar to our unit tests, with the major difference being that our integration tests actually launch our application. Due to this, these tests run considerably slower than our unit tests:

WebStorm's detailed Mocha test logging shows that our integration tests suite runs about 12 times slower than our unit test suite. At this point, this time difference is clearly negligible, but as we scale up, it can easily became a bottleneck if our integration tests are taking too long. It's important to consider this hidden time cost of higher-level testing, and reinforce why it's a good idea to have more unit tests than integration tests in your application's testing strategy.

The chai-http library we used for writing these integration tests provides two key enhancements that make working with Express REST APIs much easier. The first is the micro HTTP request library built into chai-http, which is actually its own project called Super-Agent. Super-Agent is an ultra lightweight Node.js-based request library that we are using when we are configuring our request:

chai.request(API.connection).get('/api').end();

The Super-Agent API provides many useful ways to configure your integration test for a particular endpoint of your REST API:

Method Example Description
get, post, head, delete, put, options, patch

.get('/api')

Sets the request HTTP type and target URL for an upcoming request. Only one HTTP type method may be used in a request chain.
end .end() Sends the currently configured request.
send .send({foobar: 'foobar', total: 12}) Attaches content to the body of the currently configured request. Can accept either a JSON object or a string value.
set .set('Content-Type', 'application/json') Sets a header by key and value on the currently configured request.
query .query({ order: 'asc' }) Sets a query parameter by key and an optional value on the currently configured request. Will also accept multiple parameters at once.
sortQuery
.sortQuery(function(a, b) {
return a.length - b.length;
})
Provides a sort function for determining whether the order query parameters should be serialized to the currently configured request.
type .type('form') Shortcut for setting the type of HTTP request content. Accepts string values such as json, form, png, or xml. Will also accept any valid Content-Type header value.
retry .retry(2) Sets a maximum number of retries for requests that fail to connect due to latency issues. Retry does not trigger for failure or error responses that are not network-related.
redirect .redirects(2) Set the maximum number of redirects to be followed by the request before failing. Defaults to five redirects.
accept .accept('application/json') Sets the accept header value for the currently configured request.
ca, cert, key, pfx
let cert = fs.readFileSync('cert.pem');

.cert(cert)
Sets a certificate authority, certificate file, and private key or encoded key to the currently configured request.
responseType .responseType('blob') For browse usage, this allows for handling of binary response bodies in the currently configured request. Not necessary when running inside Node.js.
abort .abort() Aborts the currently configured request.
timeout
.timeout({
response: 3000,
deadline: 40000
})
Sets timeout parameters for the currently configured request. These parameters will trigger the retry operation when reached. Values are measured in milliseconds.
auth .auth('username', 'password') Allows for the passing of basic auth parameters to the currently configured request.
attach .attach('cover', 'path/to/cover.png', 'cover.png') Sets a resource to be attached to a multipart file upload for the currently configured request. Can be used multiple times to attach multiple files to the same request.
field .field('user[email]', '[email protected]') Sets form field values for the currently configured request.
buffer req.buffer(false) Configures the current requests setting for handling buffered requests. Providing false will disable the default buffering for text to allow you to manually control file buffering.
withCredentials withCredentials() Enables CORS support through the ability to send cookies from the origin. Only works when Access-Control-Allow-Origin is not a wildcard (*), and Access-Control-Allow-Credentials is true.
on .on('error', handle) Sets an event listener for the currently configured request events. Supports common request events such as error, progress, response, send, and end.
use
import * as nocache from 'superagent-no-cache';
.use(nocache)
Adds a Super-Agent plugin to the currently configured request.

 

The Super-Agent official documentation also covers many additional details for advanced configuration options you might find useful for writing your integration tests, and is available at http://visionmedia.github.io/superagent/.

The other useful part of chai-http is the additional plugin assertions it adds to the Chai core assertion library. These assertions are oriented around the types of details you are most likely to want to assert with a response from a REST API:

Assertion Example Description
status expect(res).to.have.status(200); Asserts that the target has a status with the provided value.
header expect(req).to.have.header('Content-Type', 'text/plain'); Asserts that the target has a header with the provided key and value.
headers expect(req).to.have.headers; Asserts that the target has any HTTP headers.
ip expect('127.0.0.1').to.be.an.ip; Asserts that the target represents a valid IP address.
json, html, text expect(req).to.be.json;
expect(req).to.be.html;
expect(req).to.be.text;
Assert that a Response or Request object has the provided Content-Type header.
redirect expect(res).to.redirect; Assert that a Response object has a redirect status code.
redirectTo expect(res).to.redirectTo('http://example.com'); Asserts that a Response object has a redirect status code that matches the provided value.
param expect(req).to.have.param('orderby', 'date'); Asserts that a Request object has a query string parameter with the given key and optional value.
cookie expect(res).to.have.cookie('session_id', '1234'); Asserts that a Request or Response object has a cookie header with the given key and optional value.

 

There are many other plugins for Chai, similar to chai-http, that can further extend the power of your testings assertions within Chai.

You can learn more about the available plugins and what they do from the official Chai plugins web page at http://chaijs.com/plugins/.

One final detail worth noting is that we are launching our Express application without any database functionality. This is partially because this particular integration doesn't require it, but more than that, it's so that we can control that aspect of our tests directly instead of requiring our application to be aware that we are in a testing mode. You can very easily include the database configuration as well as the application, and set any mocks needed in the same hook we used to set up our Express application earlier. Try experimenting by adding this database configuration file back to any other integration tests you might want to create.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.91.51