【问题标题】:How to assert this promise via jest?如何通过玩笑来断言这个承诺?
【发布时间】:2017-11-08 18:06:09
【问题描述】:

我开玩笑地写了一个测试来测试我的一个中间件。

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)
    });
};

测试文件是这样的:

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);
    });
}

错误是这样的:

错误:expect(jest.fn()).toBeCalled()

预期的模拟函数已被调用。

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

这反映了这条线:

expect(mockNext).toBeCalled();

为什么它没有被调用? 我阅读了有关 jest 的文档,它说我需要返回承诺才能测试该值。但是asyncAll() 没有返回一个promise,而是消耗了一个promise,如何处理呢?

【问题讨论】:

    标签: javascript unit-testing promise mocking jestjs


    【解决方案1】:

    你必须通知 Jest 你在测试中创建的 Promise,看看这个主题的 docs

    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);
        });
    

    【讨论】:

    • 它有效。但这不应该像黑客攻击吗……我的意思是,再次运行相同的逻辑以确保当我断言时,值已经存在……
    • 在 JavaScript 中只有一个线程,所以当你调用 then 时,它不会立即执行,而是在实际堆栈完成后执行。因此,在我们的例子中,您运行测试代码,但之后会调用 promise.then 回调。 blog.risingstack.com/…
    • 谢谢!明白了!通过您的回答,我想出了如何测试 Promise.reject 案例。
    猜你喜欢
    • 2018-12-10
    • 2018-11-19
    • 1970-01-01
    • 2022-06-29
    • 1970-01-01
    • 1970-01-01
    • 2018-08-14
    • 2017-03-17
    • 2019-03-22
    相关资源
    最近更新 更多