gpt4 book ai didi

javascript - 如何使用实际模块而不是使用模拟

转载 作者:行者123 更新时间:2023-12-05 05:36:38 27 4
gpt4 key购买 nike

我有以下 Jest 配置

  jest: {
configure: {
testEnvironment: 'jsdom',
preset: 'ts-jest',
transform: {...},
moduleNameMapper: {
antd: '<rootDir>/__mocks__/antd/index.tsx'
},
testMatch: ['<rootDir>/src/**/*.test.(ts|tsx)$'],
},
},

<rootDir>/__mocks__/antd/index.tsx

class Select extends Component<SelectProps> {

static Option: FC = (props) => <option {...props} data-testid="mock-selectOption" />;

render() {
const {
...props
} = this.props;
// @ts-ignore
return <select {...props} data-testid="mock-select" />;
}
}

我有一个选择组件

import React from 'react';
import { Select as MySelect } from 'antd';

const { Option } = MySelect;

export interface SelectOption {
id: string;
label: string;
}

interface SelectProp {
options: SelectOption[];
selectedOption: string;
onChange: (key: string) => void;
}

function Select({ options, selectedOption, onChange }: SelectProp) {
return (
<MySelect value={selectedOption} onChange={onChange} >
{options.map((opt) => (
<Option key={opt.id} value={opt.id}>
{opt.label}
</Option>
))}
</MySelect>
);
}

export default Select;

我有一个测试用例

import React from 'react';
import { fireEvent } from '@testing-library/react';
import { render } from 'setupTests';

import Select from './Select';

jest.mock('antd', () => {
const originalModule = jest.requireActual('antd');
return { ...originalModule };
});

describe('Select', () => {
const handleChange = jest.fn();
const mockProps = {
options: [],
onChange: handleChange,
};
it('render successfully', () => {
const { getByTestId } = render(<Select {...mockProps} />);
getByTestId('asca'); // use for debug
});
});

getByTestId('asca')将使测试用例失败,然后我看到下面的 DOM 模态

    TestingLibraryElementError: Unable to find an element by: [data-testid="asca"]

<body>
<div>
<select
data-testid="mock-select"
/>
</div>
</body>

结果仍然使用模拟而不是实际的 antd组件。

我尝试添加

     beforeEach(() => {
jest.unmock('antd');
});

但还是得到了同样的结果。

如何使用实际模块而不是模拟模块?

最佳答案

使用jest.unmock(moduleName) API是正确的,

Indicates that the module system should never return a mocked version of the specified module from require() (e.g. that it should always return the real module).

但是你需要知道:

When using babel-jest, calls to unmock will automatically be hoisted to the top of the code block.

如果您导入 Select组件并调用 jest.unmock()beforeEach钩。运行测试用例时,mock Select组件已导入,则 beforeEach钩子(Hook)执行。开 Jest 解开 Select 为时已晚组件。

现在,您有两个选择:

__mocks__/antd/index.tsx :

import { SelectProps } from "antd/lib/select";
import React, { Component, FC } from "react";

class Select extends Component<SelectProps<any>> {
static Option: FC = (props) => <option {...props} data-testid="mock-selectOption" />;

render() {
const { ...props } = this.props;
// @ts-ignore
return <select {...props} data-testid="mock-select" />;
}
}

Select.tsx :

import React from 'react';
import { Select as MySelect } from 'antd';

const { Option } = MySelect;

export interface SelectOption {
id: string;
label: string;
}

interface SelectProp {
options: SelectOption[];
selectedOption: string;
onChange: (key: string) => void;
}

function Select({ options, selectedOption, onChange }: SelectProp) {
return (
<MySelect data-testid='asca' value={selectedOption} onChange={onChange}>
{options.map((opt) => (
<Option key={opt.id} value={opt.id}>
{opt.label}
</Option>
))}
</MySelect>
);
}

export default Select;

<强>1。调用jest.unmock() API in module scope of test file(放在import语句后即可,会被提升到代码块顶部)

import React from 'react';
import { render } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import Select from './Select';

jest.unmock('antd');

describe('Select', () => {
it('render successfully', async () => {
const handleChange = jest.fn();
const mockProps = {
options: [],
onChange: handleChange,
selectedOption: '',
};
const { getByTestId } = render(<Select {...mockProps} />);
expect(getByTestId('asca')).toBeInTheDocument();
});
});

<强>2。调用jest.unmock() API beforeEach Hook 或 it功能范围,然后动态导入 Select组件。(动态导入语句必须放在jest.unmock() API之后)

import React from 'react';
import { render } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';

describe('Select', () => {
it('render successfully', async () => {
jest.unmock('antd');
const Select = (await import('./Select')).default
const handleChange = jest.fn();
const mockProps = {
options: [],
onChange: handleChange,
selectedOption: '',
};
const { getByTestId } = render(<Select {...mockProps} />);
expect(getByTestId('asca')).toBeInTheDocument();
});
});

测试结果:

 PASS  stackoverflow/73274190/Select.test.tsx (11.55 s)
Select
✓ render successfully (1156 ms)

Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 12.049 s, estimated 13 s

jest.config.js :

module.exports = {
preset: 'ts-jest/presets/js-with-ts',
testEnvironment: 'jsdom',
setupFilesAfterEnv: ['jest-extended'],
setupFiles: ['./jest.setup.js'],
};

包版本:

"antd": "^4.16.12",
"jest": "^26.6.3",

关于javascript - 如何使用实际模块而不是使用模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73274190/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com