Reputation: 53
I'm trying to use supertest to check res.body with Jest, but the following snippet will always fail
request(app)
.post('/auth/signup')
.send(validEmailSample)
.expect(200, {
success: true,
message: 'registration success',
token: expect.any(String),
user: expect.any(Object),
});
But when I rewrite the test to check the body in a callback as follows:
test('valid userData + valid email will result in registration sucess(200) with message object.', (done) => {
request(app)
.post('/auth/signup')
.send(validEmailSample)
.expect(200)
.end((err, res) => {
if (err) done(err);
expect(res.body.success).toEqual(true);
expect(res.body.message).toEqual('registration successful');
expect(res.body.token).toEqual(expect.any(String));
expect(res.body.user).toEqual(expect.any(Object));
expect.assertions(4);
done();
});
});
The test will pass.
I'm sure it has something to do with expect.any()
. As Jest's documentation says that expect.any and expect.anything can only be used together with expect().toEqual
, and expect().toHaveBeenCalledWith()
I'm wondering if there's any better way to do it, to use expect.any in supertest's expect api.
Upvotes: 4
Views: 7827
Reputation: 166
You could assign the response to a variable and do whatever you want. I find this way easier. As you could test the body and the headers and status separately.
const app = require('./app');
const request = require('supertest');
describe('valid userData + valid email will result in registration success(200) with message object.', () => {
it('should pass', (done) => {
const res = await request(app).post('/auth/signup');
expect(res.body).toEqual(
expect.objectContaining({
success: true,
message: 'registration success',
token: expect.any(String),
user: expect.any(Object),
}),
);
});
});
Upvotes: 2
Reputation: 102587
You can use expect.objectContaining(object).
matches any received object that recursively matches the expected properties. That is, the expected object is a subset of the received object. Therefore, it matches a received object which contains properties that are present in the expected object.
app.js
:
const express = require("express");
const app = express();
app.post("/auth/signup", (req, res) => {
const data = {
success: true,
message: "registration success",
token: "123",
user: {},
};
res.json(data);
});
module.exports = app;
app.test.js
:
const app = require('./app');
const request = require('supertest');
describe('47865190', () => {
it('should pass', (done) => {
expect.assertions(1);
request(app)
.post('/auth/signup')
.expect(200)
.end((err, res) => {
if (err) return done(err);
expect(res.body).toEqual(
expect.objectContaining({
success: true,
message: 'registration success',
token: expect.any(String),
user: expect.any(Object),
}),
);
done();
});
});
});
Integration test result with coverage report:
PASS src/stackoverflow/47865190/app.test.js (12.857s)
47865190
✓ should pass (48ms)
----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
app.js | 100 | 100 | 100 | 100 | |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 14.319s
Source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/47865190
Upvotes: 11