开玩笑间谍说函数不被调用

时间:2019-07-12 10:33:32

标签: javascript typescript jestjs

调用函数sendResponse可以知道,因为sendResponse中的console.log行已执行。但是,我的间谍说sendResponse方法没有被调用。只是想知道我在做什么错。

import * as ExpressHelpers from './express-helper';

describe('sendResponse', () => {
    it('sends a 500 error response', () => {
        const sendResponseSpy = spyOn(ExpressHelpers, 'sendResponse');
        const mockResponse = () => {
            const res: any = {};
            res.status = jest.fn().mockReturnValue(res);
            res.send = jest.fn().mockReturnValue(res);
            return res;
        };
        const errorMsg = 'Server error msg';
        const res = mockResponse();
        ExpressHelpers.sendServerError(errorMsg, res);
        expect(sendResponseSpy).toHaveBeenCalled();
    });
});
export function sendResponse(statusCode: HttpStatus, message: string, data: {}, response: Express.Response) {
    const responseEntity: ResponseEntity = {
        message,
        statusCode,
        data,
    };
    response.send(responseEntity);
}

export function sendServerError(serverErrorMsg: string, res: Express.Response) {
    sendResponse(HttpStatus.SERVER_ERROR, serverErrorMsg, null, res);
}

错误:

  ● Express Helper › sendResponse › sends a 500 error response

    expect(spy).toHaveBeenCalled()

    Expected spy to have been called, but it was not called.

      35 |             const res = mockResponse();
      36 |             ExpressHelpers.sendServerError(errorMsg, res);
    > 37 |             expect(sendResponseSpy).toHaveBeenCalled();
         |                                     ^
      38 |         });
      39 |     });
      40 | });

      at Object.it (src/helpers/express-helper.test.ts:37:37)

1 个答案:

答案 0 :(得分:2)

Jest无法直接在ES模块上运行,Babel或TSC会转换您的代码,然后将其加载以执行。这种转换的结果是,您导出的函数引用现在已绑定到“导出”对象,该对象在您的源代码中不可见,但存在于正在运行的代码中。

调用spyOn时,将侦听'exports'对象(exports.sendResponse)对象内的引用,但不会侦听函数调用内的引用(sendResponse)。一种解决方案是将您的所有功能绑定到这样的某些导出对象上

function foo() { namespace.bar() }
function bar() {}

const namespace = {
    foo,
    bar
}
export default namespace;

如果感觉像是黑客,您可以使用带有静态方法的类来达到几乎相同的效果。开玩笑似乎并没有在不久的将来(https://github.com/facebook/jest/issues/4842)获得ESM支持,因此这将是更简单的解决方案之一。