使用 Jest 模拟命名导出进行测试

问题描述 投票:0回答:2

我有一个

Helper.js
文件,其中包含如下几个辅助函数,这些函数正在不同的组件中使用。

    export function buildOptions(elem) { 
        var oList=[];   
        for (var i=0; i < field.length; i++) {
            oList.push (
              <option value={options[i]["id"]}>
                  {options[i][elem]}
              </option>
            )
         }    
         return oList;
      }

      export function B(){
           .....
      }

这是一个使用

Helper.js
文件中定义的函数的组件。我正在为组件编写测试,我想模拟此处调用的外部函数。

    import React from 'react';
    import ReactDOM from 'react-dom';
    import { buildOptions, A} from './Helper.js';

    class DemoComponent extends React.Component {
        constructor(props) {
            super(props);
        }

        add(e, index) {
            ....
        }


        render() {
            var o_list=buildOptions("name");

            return (
               <div>
                  ...
                  <select required className={selectClass}  >
                      {o_list}
                  </select>  
                  ...           
                  <button type="button" onClick={(e) => this.add(e, this.props.index)}>
                        Add 
                  </button>
               </div>
            );
         };
     }

我是 Jest/Enzyme 的新手,我无法弄清楚如何模拟外部函数 buildOptions。我无法弄清楚如何模拟外部 buildOptions 函数。有人可以帮我解决这个问题吗? 这是我的测试代码:

import React from 'react';
import { mount, shallow } from 'enzyme';
import { buildOptions } from '../components/Helper.js';
import DemoComponent from '../components/DemoComponent';

describe('Democomponent', () => {

  it('should render required elements', () => {

    const wrapper = shallow(
       <DemoComponent 
        index={0}/> 
    );
    //
    tests
}); 
unit-testing mocking jestjs
2个回答
35
投票

由于您想要模拟命名导出函数,因此有一个特殊的技巧,其中涉及在测试之前使用

*
导入所有命名导出。

// your test file
import * as Helper from './Helper.js';

const originalBuildOptions = Helper.buildOptions;
Helper.buildOptions = jest.fn();

beforeEach(() => {
  jest.clearAllMocks();
  // Reset to original implementation before each test
  Helper.buildOptions.mockImplementation(originalBuildOptions);
});

test('my test', () => {
  // Mock for this test only (will be restored by next `beforeEach` call)
  Helper.buildOptions.mockImplementation(() => 'your mock');
}); 

1
投票

您还可以在导入时直接模拟默认导出和命名导出。自 2023 年起,官方笑话文档使用此方法。更新到您的用例:

// Your test file
import { buildOptions } from './Helper.js';
jest.mock('./Helper.js', () => {
    const originalModule = jest.requireActual('./Helper.js');

    // Mock any module exports here
    return {
        __esModule: true,
        ...originalModule,
        // default: jest.fn(() => 'mocked default export example'),
        // Named export mocks
        buildOptions: jest.fn(),
    };
});

这也适用于已安装的软件包。例如,我经常使用相同的导入样式覆盖特定的反应路由器挂钩,例如 useSubmit。

请参阅有关名为模拟的部分笑话的官方文档:https://jestjs.io/docs/mock-functions#mocking-partials

© www.soinside.com 2019 - 2024. All rights reserved.