Albert Gao
Albert Gao

Reputation: 3769

How to assert this promise via jest?

I write a test with jest to test one of my middleware.

const asyncAll = (req, res, next) => {
    const queue = [
        service.exchangeLongTimeToken(req),
        service.retrieveUserInfo(req),
    ];
    Promise.all(queue).then((values) => {
        res.locals.auth = values[0];
        res.locals.user = values[1];
        next();
    }).catch((err) => {
        next(err)
    });
};

The test file is like this:

const httpMocks = require('node-mocks-http');
const testData = require('../../testdata/data.json');

describe('Test asyncAll', () => {
    let spy1 = {};
    let spy2 = {};
    const mockNext = jest.fn();

    afterEach(() => {
        mockNext.mockReset();
        spy1.mockRestore();
        spy2.mockRestore();
    });

    test('Should call next() with no error when no error with 2 requests', () => {
        spy1 = jest.spyOn(service, 'exchangeLongTimeToken').mockImplementation((url) => {
            return Promise.resolve(testData.fbLongTimeToken);
        });

        spy2 = jest.spyOn(service, 'retrieveUserInfo').mockImplementation((url) => {
            return Promise.resolve(testData.fbUserInfo);
        });

        const request = httpMocks.createRequest();
        const response = httpMocks.createResponse();

        asyncAll(request, response, mockNext);

        expect(spy1).toBeCalled();
        expect(spy2).toBeCalled();
        expect(mockNext).toBeCalled();
        expect(mockNext).toBeCalledWith();
        expect(mockNext.mock.calls.length).toBe(1);
    });
}

The error is like this:

Error: expect(jest.fn()).toBeCalled()

Expected mock function to have been called.

  at Object.<anonymous> (tests/backend/unit/fblogin/asyncAll.test.js:39:26)

Which reflects the line:

expect(mockNext).toBeCalled();

Why it doesn't get called? I read the documents about jest, it says I need to return the promise in order to test the value. But the asyncAll() doesn't return a promise, instead, it consumes a promise, how to deal with this?

Upvotes: 2

Views: 2576

Answers (1)

Andreas K&#246;berle
Andreas K&#246;berle

Reputation: 110922

You have to notify Jest about the promises you create in the test, have a look at the docs on this topic:

test('Should call next() with no error when no error with 2 requests', async() => {
        const p1 = Promise.resolve(testData.fbLongTimeToken);
        const p2 = Promise.resolve(testData.fbUserInfo);
        spy1 = jest.spyOn(service, 'exchangeLongTimeToken').mockImplementation((url) => {
            return p1
        });

        spy2 = jest.spyOn(service, 'retrieveUserInfo').mockImplementation((url) => {
            return p2
        });

        const request = httpMocks.createRequest();
        const response = httpMocks.createResponse();

        asyncAll(request, response, mockNext);
        await Promise.all([p1,p2])
        expect(spy1).toBeCalled();
        expect(spy2).toBeCalled();
        expect(mockNext).toBeCalled();
        expect(mockNext).toBeCalledWith();
        expect(mockNext.mock.calls.length).toBe(1);
    });

Upvotes: 2

Related Questions