【问题标题】:Use `jest.spyOn` on an exported function from a Node module在从 Node 模块导出的函数上使用 `jest.spyOn`
【发布时间】:2019-12-28 08:37:16
【问题描述】:

Jest 中,为了监视(并可选择模拟实现)方法,我们执行以下操作:

const childProcess = require('child_process');
const spySpawnSync = jest.spyOn(childProcess, 'spawnSync').mockImplementation();

这允许我们使用spySpawnSync 来检查上次调用它时使用的参数,如下所示:

expect(spySpawnSync).lastCalledWith('ls');

但是,这对于导出函数的 Node 模块是不可能的,例如 execa 包。

我尝试了以下每一个,但没有一个可以窥探或模拟函数:

// Error: `Cannot spy the undefined property because it is not a function; undefined given instead`
jest.spyOn(execa);

// Error: `Cannot spyOn on a primitive value; string given`
jest.spyOn('execa');

// Error: If using `global.execa = require('execa')`, then does nothing. Otherwise, `Cannot spy the execa property because it is not a function; undefined given instead`.
jest.spyOn(global, 'execa');

因此,有没有办法监视导出函数的模块,例如给定示例中的execa

【问题讨论】:

    标签: node.js unit-testing mocking jestjs spy


    【解决方案1】:

    我们可以尝试在测试开始时模拟模块本身,例如在 describe 块之前,如下所示:

    jest.mock('execa’, () => ({
      Method1: jest.fn(),
      Method2: jest.fn().mockReturnValue(…some mock value to be returned)
    }));
    

    这里的Method1Method2 是您想要模拟和测试的一些execa 方法,或者如果您正在使用它们。

    否则,您可以像下面这样模拟,它应该可以工作:

    jest.mock('execa');
    

    【讨论】:

      【解决方案2】:

      我对@9​​87654321@ 有完全相同的需求和问题,下面是我的工作方式:

      import execa from 'execa'
      
      
      jest.mock('execa', () => jest.fn())
      
      test('it calls execa', () => {
        runSomething()
        expect(execa).toHaveBeenCalled()
      })
      
      

      所以基本上,由于导入的模块是函数本身,你所做的就是用jest.mock 模拟整个模块,并简单地返回一个 Jest 模拟函数作为它的替换。

      由于 jest.fn()jest.spyOn() 在底层所依赖的,因此您可以从测试中的相同断言方法中受益 :)

      【讨论】:

      • @oliver-lance,我喜欢你的回答。当我只想验证模块函数是否已被调用时,它适用于我的用例。但是,在测试多次调用它并根据第二次调用的响应采用不同路径的用户定义函数时,我试图模拟对execa 的每次调用的响应。这似乎很难。我正在尝试确定如何最好地进行。我正在考虑使用基于参数包装每种调用类型的方法创建一个类。模拟类的每个方法相对容易。
      • 你可以为execa 使用模拟实现而不是我使用的空模拟函数吗?像这样:jest.fn(cmd => doSomething())你当然会有一个更复杂的主体,但至少你可以根据可执行路径控制你的模拟函数的返回值
      猜你喜欢
      • 2021-08-29
      • 1970-01-01
      • 1970-01-01
      • 2017-05-07
      • 1970-01-01
      • 1970-01-01
      • 2019-04-26
      • 2017-01-11
      • 1970-01-01
      相关资源
      最近更新 更多