【问题标题】:Mock a namespace and a function with same name using Jest使用 Jest 模拟名称空间和具有相同名称的函数
【发布时间】:2017-12-23 20:12:43
【问题描述】:

我正在使用的库的结构为

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'

【问题讨论】:

    标签: node.js typescript mocking jestjs


    【解决方案1】:

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

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

    查看Jest manual 了解更多信息

    【讨论】:

      【解决方案2】:

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

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

      或者干脆

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

      模拟一个。

      【讨论】:

        【解决方案3】:

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

        我建议你嵌套命名空间。

        您可以将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)
            });
        })
        

        【讨论】:

          【解决方案4】:

          尽管这篇文章的主要 OP 已经很老了,但我会添加 大部分正确的方法

          namespaces 最终只是原始的 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
            };
          });
          

          【讨论】:

            猜你喜欢
            • 2021-12-23
            • 1970-01-01
            • 1970-01-01
            • 2018-06-25
            • 2016-01-04
            • 2019-12-17
            • 1970-01-01
            • 2011-03-10
            相关资源
            最近更新 更多