【问题标题】:React: How to cover dynamic imports in Jest tests?React:如何在 Jest 测试中涵盖动态导入?
【发布时间】:2020-06-02 21:09:12
【问题描述】:

所以我有一个使用的反应组件:

const MyPage = DynamicImport({
  id: 'MyPage',
  loader: () => import('./pages/MyPage/MyPageWrapper'),
});

开玩笑地抱怨说我的测试没有涵盖加载程序,第 22 行:

然后在同一个文件中使用它:

const tabs = useMemo(
    () => [
      {
        label: 'myPage',
        url: 'myRoute',
        component: MyPage,
      },
      ...

最后

{tabs.map(({ url, component }) => {
  return <Route path={url} component={component} key={url} />;
})}

我正在学习如何编写单元测试,但我不知道如何在屏幕截图上用红线覆盖这一部分,显然我一直在谷歌搜索并寻找答案,但我找不到任何有用的东西。

这是我的测试文件:

import React from 'react';
import { MyComponent } from '../MyComponent';
import { makeSetupComponent } from '../../../../test_utils';

const MyPage = () => ({
  id: '',
  loader: jest.fn(),
});

jest.mock('../pages/MyPage/MyPageWrapper', () => {
  return {
    MyPageWrapper: jest.fn(),
  };
});

const defaultProps = {
  ...
  };

const setup = makeSetupComponent({
  props: defaultProps,
  shallow: true,
  component: MyComponent,
});

describe('MyComponent component', () => {
  test('Renders correctly', () => {
    const { component } = setup();
    expect(component.exists()).toBe(true);
  });

  test('render MyPage', () => {
    const { component } = setup({ shallow: false });
    console.log('###DEBUG', component.debug());
    console.log('###MyPage', MyPage);

    const { loader } = MyPage();
    loader();

    expect(MyPage).toBeInstanceOf(Function);
    expect(loader).toHaveBeenCalled();
  });
});

任何帮助/建议/链接/课程-完全覆盖-这将不胜感激

【问题讨论】:

  • 测试是什么?给minimal reproducible example
  • @jonrsharpe 我刚刚编辑了添加我的测试文件的帖子,这是我的尝试,但当然,这段代码没有覆盖你在我的截图上看到的红线,这就是我的目标.
  • 不清楚你为什么会有其他期望;看起来一切都被嘲笑了,没有什么可以测试了。
  • @jonrsharpe 抱歉,说清楚我想增加覆盖率,如果你查看我帖子中的屏幕截图,它会说第 22 行没有被覆盖,我希望覆盖它,所以我是询问是否有人知道如何实现它
  • 是的,这很清楚。您是否尝试过测试实际的 MyPage 而不是您在测试中构建的假的?

标签: javascript reactjs unit-testing jestjs


【解决方案1】:

这里是单元测试解决方案:

DynamicImport.ts:

export async function DynamicImport({ id, loader }) {
  console.log('real implementation');
  return loader();
}

MyPageWrapper.ts

export function MyPageWrapper() {
  return 'MyPageWrapper';
}

index.ts:

import { DynamicImport } from './DynamicImport';

export function main() {
  return DynamicImport({
    id: 'MyPage',
    loader: () => import('./MyPageWrapper'),
  });
}

index.test.ts:

import { main } from './';
import { DynamicImport } from './DynamicImport';
import { mocked } from 'ts-jest/utils';

jest.mock('./DynamicImport', () => {
  return {
    DynamicImport: jest.fn(),
  };
});

jest.mock('./MyPageWrapper', () => ({
  __esModule: true,
  default: 'mocked MyPageWrapper',
}));

describe('62161452', () => {
  it('should pass', async () => {
    mocked(DynamicImport).mockImplementationOnce(({ id, loader }) => {
      console.log('mocked implementation');
      return loader();
    });
    const actual = (await main()).default;
    expect(actual).toBe('mocked MyPageWrapper');
    expect(DynamicImport).toBeCalledWith({ id: 'MyPage', loader: expect.any(Function) });
  });
});

带有覆盖率报告的单元测试结果:

 PASS  stackoverflow/62161452/index.test.ts (9.149s)
  62161452
    ✓ should pass (32ms)

  console.log
    mocked implementation

      at Object.<anonymous> (stackoverflow/62161452/index.test.ts:19:15)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |                   
 index.ts |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        10.178s

测试覆盖率 html 记者:

【讨论】:

  • 这太棒了!谢谢你!我会用什么代替 mocked() ?我的项目没有 TS,我认为我无法在 atm 上进行此更改
  • @WagnerMoreira 如果您使用 JS,只需删除 mocked。其他都一样
猜你喜欢
  • 2021-12-09
  • 2018-04-02
  • 1970-01-01
  • 2020-06-03
  • 2019-03-11
  • 2018-03-22
  • 2018-07-25
  • 2019-06-09
  • 2023-04-11
相关资源
最近更新 更多