【问题标题】:Mocking an ES6 class function with Jest用 Jest 模拟 ES6 类函数
【发布时间】:2018-03-12 01:30:28
【问题描述】:

我有一个关于如何使用 Jest 模拟 ES6 类实例的问题,该实例由我实际想要测试的方法使用。 我的真实案例是尝试测试一个 Redux 异步操作创建器,它发出请求并根据请求结果分派一些操作。

这是用例的简化示例:

// communication.js
// An exported ES6 class module with proxy to the request library.
import post from './post';
export default class communication {

    getData(data, success, error) {
        const res = post(data);
        if(res) {
            success();
        } else {
            error();
        }
    }
}

// communicatorAssist.js
// A redux async function using communication.js
import communication from './communication';
// ...

export function retrieveData() {
    return dispatch => {
        const data = { name: 'michel'};
        communication.getData(data,
            (res) => dispatch(successAction(res)),
            (res) => dispatch(errorAction(res));
    }
}

// communicatorAssist.test.js testing the communicatorAssist
import { retrieveData } from 'communicatorAssist';

// communication.getData should call success callback
// for this test.
it('Should call the success callback', () => {
    retrieveData();
    // Assert that mocked redux store contains actions
});

// communication.getData should call error callback
// for this test.
it('Should call the error callback', () => {
    retrieveData();
    // Assert that mocked redux store contains actions
});

我想要的是在测试中模拟通信类,并更改每个测试中 getData() 函数的行为以调用 successerror 回调而不调用 post 方法。

我只成功地模拟了整个测试文件的 getData() 函数,并在其顶部使用了这个 sn-p:

import communication from '../communication'
jest.mock('../communication', () => (() => ({
    getData: (success, error) => success()
})));

但我无法在不同测试用例的实现之间切换。

我认为使用 .mockImplementation() 的东西可以做到这一点,但在我的情况下我无法做到这一点(我看到了将其用于模块导出功能但不适用于类的示例)。

有人有想法吗?

编辑

我忘记了代码示例中的一部分:我认为创建通信类实例是模拟它的“问题”:

const com = new communication();

如果 com 在 communicatorAssist.js 文件中的全局级别被实例化:它会因 communication.getData is not a function 错误而失败。

但如果我在 retrieveData() 函数中设置实例化,Andreas Köberle sn-p 工作正常:

import communication from '../communication'
jest.mock('../communication', () => jest.fn());

communication.mockImplementation(
  () => ({
    getData: (success, error) => success()
  })
)

(jest.mock()工厂参数需要返回一个函数而不是直接jest.fn)

我不知道为什么它不能使用文件全局范围实例。

【问题讨论】:

    标签: javascript unit-testing react-redux jestjs


    【解决方案1】:

    您需要使用jest.fn() 模拟模块,然后您可以导入它并使用mockImplementation 更改它的行为:

    import communication from '../communication'
    jest.mock('../communication', jest.fn());
    
    communication.mockImplementation(
      () => ({
        getData: (success, error) => success()
      })
    )
    

    【讨论】:

    • 我已经用你的答案编辑了问题,如果通信类在retrieveData函数中实例化,效果很好。
    • 如果 getData 的结果必须在此测试文件中的测试中有所不同怎么办?
    • @Marc 然后创建各种不同的通信模拟,每个模拟都有自己模拟的 getData 函数。
    • 第二行产生以下错误The second argument of `jest.mock` must be an inline function
    猜你喜欢
    • 1970-01-01
    • 2018-05-04
    • 2017-09-30
    • 1970-01-01
    • 2019-03-22
    • 2016-04-09
    • 2020-09-09
    • 2021-11-24
    • 2022-06-29
    相关资源
    最近更新 更多