Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test response data from Express in Jest

I'm writing unit tests for separate middleware functions in Node/Express using Jest.

A simple example of the middleware:

function sendSomeStuff(req, res, next) {
    try {
        const data = {'some-prop':'some-value'};

        res.json(data);
        next();
    } catch (err) {
        next(err);
    }
}

And a sample of my test suite:

const httpMocks = require('node-mocks-http');
const { sendSomeStuff } = require('/some/path/to/middleware');

describe('sendSomeStuff', () => {
    test('should send some stuff', () => {
        const request = httpMocks.createRequest({
            method: 'GET',
            url: '/some/url'
        });

        let response = httpMocks.createResponse();

        sendSomeStuff(request, response, (err) => {
            expect(err).toBeFalsy();

            // How to 'capture' what is sent as JSON in the function?
        });
    });
});

I have to provide a callback to populate the next parameter, which is called in the function. Normally, this would 'find the next matching pattern', and pass the req and res objects to that middleware. However, how can I do this in a test set-up? I need to verify the JSON from the response.

I don't want to touch the middleware itself, it should be contained in the test environment.

Am I missing something here?

like image 408
lennyklb Avatar asked Jul 20 '17 08:07

lennyklb


People also ask

Can I use Jest for API testing?

Jest is great for validation because it comes bundled with tools that make writing tests more manageable. While Jest is most often used for simple API testing scenarios and assertions, it can also be used for testing complex data structures.


1 Answers

Found a fix! Leaving this here for someone else who might struggle with the same.

When returning data using res.send(), res.json() or something similar, the response object (from const response = httpMocks.createResponse();) itself is updated. The data can be collected using res._getData():

const httpMocks = require('node-mocks-http');
const { sendSomeStuff } = require('/some/path/to/middleware');

describe('sendSomeStuff', () => {
    test('should send some stuff', () => {
        const request = httpMocks.createRequest({
            method: 'GET',
            url: '/some/url'
        });

        const response = httpMocks.createResponse();

        sendSomeStuff(request, response, (err) => {
            expect(err).toBeFalsy();
        });

        const { property } = JSON.parse(response._getData());

        expect(property).toBe('someValue');
        });
    });
});
like image 101
lennyklb Avatar answered Jan 02 '23 21:01

lennyklb