How to unit test a Node.js module that requires other modules and how to mock the global require function?

后端 未结 8 2072
我在风中等你
我在风中等你 2020-11-29 16:38

This is a trivial example that illustrates the crux of my problem:

var innerLib = require(\'./path/to/innerLib\');

function underTest() {
    return innerLi         


        
8条回答
  •  南方客
    南方客 (楼主)
    2020-11-29 17:24

    If you've ever used jest, then you're probably familiar with jest's mock feature.

    Using "jest.mock(...)" you can simply specify the string that would occur in a require-statement in your code somewhere and whenever a module is required using that string a mock-object would be returned instead.

    For example

    jest.mock("firebase-admin", () => {
        const a = require("mocked-version-of-firebase-admin");
        a.someAdditionalMockedMethod = () => {}
        return a;
    })
    

    would completely replace all imports/requires of "firebase-admin" with the object you returned from that "factory"-function.

    Well, you can do that when using jest because jest creates a runtime around every module it runs and injects a "hooked" version of require into the module, but you wouldn't be able to do this without jest.

    I have tried to achieve this with mock-require but for me it didn't work for nested levels in my source. Have a look at the following issue on github: mock-require not always called with Mocha.

    To address this I have created two npm-modules you can use to achieve what you want.

    You need one babel-plugin and a module mocker.

    • babel-plugin-mock-require
    • jestlike-mock

    In your .babelrc use the babel-plugin-mock-require plugin with following options:

    ...
    "plugins": [
            ["babel-plugin-mock-require", { "moduleMocker": "jestlike-mock" }],
            ...
    ]
    ...
    

    and in your test file use the jestlike-mock module like so:

    import {jestMocker} from "jestlike-mock";
    ...
    jestMocker.mock("firebase-admin", () => {
                const firebase = new (require("firebase-mock").MockFirebaseSdk)();
                ...
                return firebase;
    });
    ...
    

    The jestlike-mock module is still very rudimental and does not have a lot of documentation but there's not much code either. I appreciate any PRs for a more complete feature set. The goal would be to recreate the whole "jest.mock" feature.

    In order to see how jest implements that one can look up the code in the "jest-runtime" package. See https://github.com/facebook/jest/blob/master/packages/jest-runtime/src/index.js#L734 for example, here they generate an "automock" of a module.

    Hope that helps ;)

提交回复
热议问题