Table of contents
1.
Introduction
2.
Installation
2.1.
chai-http Addons
3.
Integration Testing
3.1.
App or Server
3.2.
URL
3.3.
Setting up requests
3.4.
Traditional Method of Dealing with response
3.4.1.
Caveat
3.5.
Promises
3.6.
Retention of Cookies
4.
Assertions
4.1.
.status(code)
4.2.
.header(key [,value])
4.3.
.headers
4.4.
.ip
4.5.
.json or .text or .html
4.6.
.redirect
4.7.
.param
4.8.
.cookie
5.
FAQs
6.
Key Takeaways
Last Updated: Mar 27, 2024
Easy

HTTP Response Assertions in ChaiJs

Author Aman Thakur
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

chai-http is a HTTP(Hyper-Text-Transmission-Protocol) integration testing module that allows you to test API endpoints using chai assertions. Have you ever pondered why this feature is so important? Actually, this offers the developer assurance that the functionality they're working on will operate properly without affecting the production code.
 

Let us see what all features do it provide to us:

1. request composition for integration test
2. http apps or external services are put to the test
3. assertions for frequently used http tasks
4. expect and should interfaces chai

This article will discuss the setup and usage of the chai-http package.

Installation

This addon plugin can be installed using yarn or npm according to the package manager of your choice as follows

If you are using npm 

npm install chai-http

Or if you are using yarn

yarn add chai-http

chai-http Addons

Use this plugin just like any other Chai plugin.

var chai = require("chai"),
chaiHttp = require("chai-http");
chai.use(chaiHttp);
You can also try this code with Online Javascript Compiler
Run Code

Simply include the dist/chai-http.js file in a web page to utilise Chai HTTP.

<script src="chai.js"></script>
<script src="chai-http.js"></script>
<script>
chai.use(chaiHttp);
</script>

Integration Testing

chai-http provides a superagent-based interface for live integration testing. To do so, you must first create an application or url request.

When you create it, you are given a chainable api that lets you define the http request (get, post, etc) that you wish to make.

App or Server

A node or a function (like an express or connect app) can be utilised. Your request will be built on a javascript http(s) server. chai-http will locate an appropriate port to listen on for a given test if the server is not running.

This feature is only accessible in Node.js and cannot be used in web browsers.

chai.request(app).get("/");
You can also try this code with Online Javascript Compiler
Run Code

When you send an app a request, it will automatically open the server for incoming requests (by using listen()) and then shut it down (by calling.close()) after a request has been made.

If you wish to leave the server open while performing numerous requests, call.keepOpen() after.request() and manually shut the server:

var req = chai.request(app).keepOpen()

Promise.all([
req.get('/a'),
req.get('/b'),
])
.then(res => ....)
.then(() => req.close())
You can also try this code with Online Javascript Compiler
Run Code

URL

The method enables us to call for the request at the root url endpoint.

chai.request('http://localhost:8001').get('/')
You can also try this code with Online Javascript Compiler
Run Code

Setting up requests

With a simple API, headers, form data, json, and even file attachments may be added to a request generated with a particular VERB (i.e, headers which are attached with request/response):

// Send some JSON
chai
.request(app)
.put("/user/codingninja")
.set("X-API-Key", "foobar")
.send({ password: "codingninjas", confirmPassword: "codingninjas" });

// Send some Form Data
chai.request(app).post("/user/me").type("form").send({
_method: "put",
password: "codingninjas",
confirmPassword: "codingninjas",
});

// Attach a file
chai
.request(app)
.post("/user/avatar")
.attach("imageField", fs.readFileSync("codingninja.png"), "codingninja.png");

// Authenticate with Basic authentication
chai.request(app).get("/protected").auth("user", "pass");

chai.request(app).get("/search").query({ user-name: "coding-ninja", limit: 11 }); 
// /search?user-name=coding-ninja&limit=11
You can also try this code with Online Javascript Compiler
Run Code

Traditional Method of Dealing with response

We'll utilise Chai's Expect assertion library in the following examples:

var expect = chai.expect;
You can also try this code with Online Javascript Compiler
Run Code

The end method may be used to make the request and assert on its response:

chai
.request(app)
.put("/user/me")
.send({ password: "123", confirmPassword: "123" })
.end(function (err, res) {
  expect(err).to.be.null;
  expect(res).to.have.status(200);
});
You can also try this code with Online Javascript Compiler
Run Code

Caveat

Assertions are executed asynchronously since the end function is supplied a callback.

As a result, a means to tell the testing framework that the callback has completed is required. Otherwise, the test will pass without checking the assertions.

For example, the done callback in the Mocha test framework does this by signalling that the callback has completed and the assertions may be verified:

it("fails, as expected", function (done) {
 // <= Pass in done callback
chai
  .request("http://localhost:8080")
  .get("/")
  .end(function (err, res) {
    expect(res).to.have.status(123);
    done(); // <= Call done to signal callback end
  });
});

it("succeeds silently!", function () {
 // <= No done callback
chai
  .request("http://localhost:8080")
  .get("/")
  .end(function (err, res) {
    expect(res).to.have.status(123); // <= Test completes before this runs
  });
});
You can also try this code with Online Javascript Compiler
Run Code

When done is specified, Mocha will wait until done() is called or the timeout expires.

When signalling completion, done also accepts an error argument.

Promises

Here I am assuming that the version of Nodejs which you are using is greater than 10. Request() becomes a Promise capable library if Promise is provided, allowing for chaining of then:

chai
.request(app)
.put("/user/me")
.send({ password: "codingninjas", confirmPassword: "codingninjas" })
.then(function (res) {
  expect(res).to.have.status(200);
})
.catch(function (err) {
  throw err;
});
You can also try this code with Online Javascript Compiler
Run Code

Retention of Cookies

You may need to save cookies from one request and send them with a subsequent request (For example, if you wish to login with the initial request and then access a resource that requires authentication later). .request.agent() may be used for this:
 

// Log in
var agent = chai.request.agent(app);
agent
.post("/session")
.send({ username: "coding-ninja", password: "codingninja" })
.then(function (res) {
  expect(res).to.have.cookie("sessionid");
  return agent.get("/user/coding-ninja").then(function (res) {
    expect(res).to.have.status(200);
  });
});
You can also try this code with Online Javascript Compiler
Run Code

Assertions

For the expect and should interfaces, the Chai HTTP module provides a number of assertions.

.status(code)

@param {Number} status number

Assert that a response's status is delivered.

expect(res).to.have.status(200);
You can also try this code with Online Javascript Compiler
Run Code

.header(key [,value])

@param {String} header key (case insensitive)
@param _{String RegExp}_ header value (optional)

Assert the existence of a header in a Response or Request object.If a value is specified, equality to that value is guaranteed.To check, you may also pass a regular expression.

Note that the same-origin policy only enables Chai HTTP to read specific headers when executing in a web browser, which might cause assertions to fail.

expect(req).to.have.header('x-api-key');
expect(req).to.have.header('content-type', 'text/plain');
expect(req).to.have.header('content-type', /^text/);
You can also try this code with Online Javascript Compiler
Run Code

.headers

Assert the existence of headers in a Response or Request object.

Note that the same-origin policy only enables Chai HTTP to read specific headers when executing in a web browser, which might cause assertions to fail.

expect(req).to.have.headers;
You can also try this code with Online Javascript Compiler
Run Code

.ip

expect('127.0.0.2').to.be.an.ip;
expect('2001:0db8:85a3:0000:0000:8a2e:0370:7334').to.be.an.ip;
You can also try this code with Online Javascript Compiler
Run Code

.json or .text or .html

Ascertain the content-type of a Response or Request object.

expect(req).to.be.json;
expect(req).to.be.html;
expect(req).to.be.text;
You can also try this code with Online Javascript Compiler
Run Code

.redirect

@param _{StringRegExp}_ location url

Assert that a Response object sends the user to the specified URL.

expect(res).to.redirectTo('http://example.com');
expect(res).to.redirectTo(/^\/search\/results\?orderBy=desc$/);
You can also try this code with Online Javascript Compiler
Run Code

.param

@param {String} parameter name
@param {String} parameter value

Assert that a Request object has a query string parameter with the provided key and value (optionally).

expect(req).to.have.param('orderby');
expect(req).to.have.param('orderby', 'date');
expect(req).to.not.have.param('limit');
You can also try this code with Online Javascript Compiler
Run Code

.cookie

@param {String} parameter name
@param {String} parameter value

Ascertain if a Request or Response object includes a cookie header with the specified key and (optionally) value.

expect(req).to.have.cookie('session_id');
expect(req).to.have.cookie('session_id', '1234');
expect(req).to.not.have.cookie('PHPSESSID');
expect(res).to.have.cookie('session_id');
expect(res).to.have.cookie('session_id', '1234');
expect(res).to.not.have.cookie('PHPSESSID');
You can also try this code with Online Javascript Compiler
Run Code

FAQs

1. What is chai in Webdriverio?
Ans: For the Chai assertion library, it provides webdriverio sugar. Makes it possible to write expressive integration tests.

2. What does it mean to say Chai is an assertion library?
Ans: Chai is an assertion library that is frequently used in conjunction with Mocha.It includes functions and methods that allow you to compare a test's output to its expected result. Chai has a simple syntax that reads almost like English.

3. What is Sinon chai?
Ans: With the Chai assertion library, Sinon–Chai provides a set of custom assertions for using the Sinon.JS spy, stub, and mocking framework. You get all of the benefits of Chai plus all of Sinon's amazing tools.

4. What is assertion in Cypress?
Ans: Assertions are checkpoints in an automated test case that confirm if a test step passed or failed. As a result, it verifies that the application under test is in the intended condition. For assertions, Cypress includes the Chai, JQuery, and Sinon libraries.

Key Takeaways

If you've made it this far, it's safe to assume you enjoyed reading the post. This article emphasises over request composition for integration tests, http apps or external services are put to the test, assertions for frequently used http tasks and elaborate their usages.

You might be interested in articles such as Fundamentals of Software TestingDeep-Eql utilities and check-errors in chai. If that is not enough you can just head over to our practice platform Coding Ninjas Studio to practise top problems, attempt mock tests, read interview experiences, and much more. If you like this article do upvote it.

Happy Learning

Live masterclass