使用Jest模拟名称空间和具有相同名称的函数

时间:2017-07-18 19:35:53

标签: node.js typescript mocking jest

我使用的库结构为

declare namespace foo {
  function bar();
};

declare namespace foo.bar {
  function baz();
};

因此我需要模拟的两个函数是foo.bar()foo.bar.baz()

模仿foo.bar()我以前使用

require('foo');

jest.mock('foo', () => ({
  bar: () => mockedBar,
}));

有没有办法模仿foo.bar.baz()?我试过了

jest.mock('foo.bar', () => ({
}));

但是它显示了一条消息Cannot find module 'foo.bar' from 'functions.test.js'

4 个答案:

答案 0 :(得分:1)

您可以在项目根目录的__mocks__文件夹中(在jest config中定义!)为模块定义自定义模拟。因此,您可以使用模拟的__mocks__/foo.js模块功能创建foo,Jest会自动加载该模块以进行测试。您还可以指定模拟的自定义路径:

jest.mock('foo', () => jest.requireActual('../some/another/folder/foo.js'));

检查Jest manual以获得更多信息

答案 1 :(得分:1)

如果'foo'在全局下,则可以尝试在测试脚本的开头添加以下代码。或将它们写入.js文件中,并在第一行中导入。

Object.defineProperty(global, "foo", {
    value: {
        bar: {
            baz: ()=>{
                 return true;
               },
            },
        },
    },
});

或者简单地

global["foo"] = {
    bar: {
        baz: () => {
            return true;
        },
    },
};

模拟一个。

答案 2 :(得分:0)

根据文档,在名称中使用圆点是可以的,但是我对此有一种直觉。

我建议您嵌套名称空间。

您可以将bar的声明包含在foo

declare namespace foo {
  function bar();

  declare namespace bar {
    function baz();
  };

};

概念证明

foo.ts

export namespace foo {
    export function bar() { return "bar"}

    export namespace bar {
        function baz() { return "baz"}
    }
}

foo.test.ts

import {foo} from "./foo"

describe("jest-mock-namespace", () => {
    it("Should mock foo.bar to return whatever we want", () => {
        const WWW = "WHATEVER_WE_WANT";
        // @ts-ignore
        foo.bar = jest.fn().mockImplementationOnce( () => WWW);

        const result = foo.bar();

        expect(result).toStrictEqual(WWW)
    });

    it("Should mock foo.bar.baz to return whatever we want", () => {
        const WWW = "WHATEVER_WE_WANT";
        // @ts-ignore
        foo.bar.baz = jest.fn().mockImplementationOnce( () => WWW);

        // @ts-ignore
        const result = foo.bar.baz();

        expect(result).toStrictEqual(WWW)
    });
})

答案 3 :(得分:0)

尽管这篇文章是主要的 OP 已经很老了,但我会添加大多数正确的方法来做这个。

namespace 最后只是原始 JavaScript Function 对象,当您开始将 namespace 视为对象时,模拟这些最终会很简单。

然后是以下结构:

declare namespace foo {
  function bar();
};

declare namespace foo.bar {
  function baz();
};

可以使用 Jest 模拟如下:

jest.mock('foo', () => {
  const bar = jest.fn().mockImplementation();
  bar.baz = jest.fn().mockImplementation();
  return {
    bar
  };
});