乐闻世界logo
搜索文章和话题

面试题手册

如何在 Jest 中跳过和隔离测试?如何使用 test.skip、test.only 和 describe.only?

Jest 提供了多种跳过和隔离测试的方法,用于在开发过程中专注于特定测试:1. 跳过单个测试:test.skip('this test is skipped', () => { expect(true).toBe(false);});// 或使用 xtestxtest('this test is also skipped', () => { expect(true).toBe(false);});2. 跳过测试套件:describe.skip('skipped suite', () => { test('this test will not run', () => { expect(true).toBe(false); });});// 或使用 xdescribexdescribe('also skipped suite', () => { test('this test will not run', () => { expect(true).toBe(false); });});3. 只运行特定测试:test.only('only this test runs', () => { expect(true).toBe(true);});test('this test is skipped', () => { expect(true).toBe(false);});// 或使用 fitfit('only this test runs', () => { expect(true).toBe(true);});4. 只运行特定测试套件:describe.only('only this suite runs', () => { test('this test runs', () => { expect(true).toBe(true); });});describe('this suite is skipped', () => { test('this test is skipped', () => { expect(true).toBe(false); });});// 或使用 fdescribefdescribe('only this suite runs', () => { test('this test runs', () => { expect(true).toBe(true); });});5. 条件性跳过测试:const skipIf = (condition, testName, testFn) => { const testOrSkip = condition ? test.skip : test; testOrSkip(testName, testFn);};skipIf(process.env.CI, 'skip in CI', () => { expect(true).toBe(true);});6. 使用命令行过滤测试:# 只运行匹配模式的测试jest --testNamePattern="should add"# 只运行特定文件jest path/to/test.spec.js# 只运行修改过的文件相关测试jest --onlyChanged最佳实践:使用 .only 进行调试,完成后移除使用 .skip 暂时禁用失败的测试避免提交包含 .only 或 .skip 的代码使用命令行选项进行临时测试过滤在 CI/CD 中使用 --onlyFailures 只运行失败的测试
阅读 0·2月21日 15:54

如何在 Jest 中测试 API 调用和网络请求?如何 Mock fetch 和 Axios?

在 Jest 中测试 API 调用和网络请求需要使用 Mock 来隔离外部依赖:1. Mock fetch API:global.fetch = jest.fn(() => Promise.resolve({ json: () => Promise.resolve({ data: 'test' }) }));test('fetches data from API', async () => { const data = await fetchData(); expect(data).toEqual({ data: 'test' }); expect(fetch).toHaveBeenCalledTimes(1);});2. Mock Axios:import axios from 'axios';jest.mock('axios');test('fetches user data', async () => { const mockData = { name: 'John', age: 30 }; axios.get.mockResolvedValue({ data: mockData }); const result = await getUser(1); expect(result).toEqual(mockData); expect(axios.get).toHaveBeenCalledWith('/users/1');});3. Mock 模块导出:// api.jsexport const fetchData = () => fetch('/api/data');// api.test.jsimport { fetchData } from './api';import fetch from 'node-fetch';jest.mock('node-fetch');test('fetches data', async () => { fetch.mockResolvedValue({ json: () => ({ data: 'test' }) }); const result = await fetchData(); expect(result).toEqual({ data: 'test' });});4. 测试错误处理:test('handles API errors', async () => { axios.get.mockRejectedValue(new Error('Network Error')); await expect(getUser(1)).rejects.toThrow('Network Error');});5. 测试不同的响应状态:test('handles 404 error', async () => { axios.get.mockRejectedValue({ response: { status: 404, data: { message: 'Not found' } } }); await expect(getUser(1)).rejects.toMatchObject({ response: { status: 404 } });});6. 使用 MSW(Mock Service Worker):import { rest } from 'msw';import { setupServer } from 'msw/node';const server = setupServer( rest.get('/api/users', (req, res, ctx) => { return res(ctx.json({ name: 'John' })); }));beforeAll(() => server.listen());afterEach(() => server.resetHandlers());afterAll(() => server.close());test('fetches user with MSW', async () => { const user = await fetchUser(); expect(user).toEqual({ name: 'John' });});最佳实践:使用 Mock 隔离外部 API 依赖测试成功和失败场景验证请求参数和响应处理清理 Mock 以避免测试污染考虑使用 MSW 进行更真实的 API 模拟
阅读 0·2月19日 19:55

如何在 Jest 中测试 React 组件?常用的测试工具和查询方法有哪些?

在 Jest 中测试 React 组件需要结合测试工具和渲染方法:常用测试工具:@testing-library/react:官方推荐的 React 测试库react-test-renderer:用于快照测试enzyme:传统的 React 组件测试工具(较少使用)基本测试示例:import { render, screen, fireEvent } from '@testing-library/react';import Button from './Button';test('renders button with text', () => { render(<Button>Click me</Button>); expect(screen.getByText('Click me')).toBeInTheDocument();});test('calls onClick when clicked', () => { const handleClick = jest.fn(); render(<Button onClick={handleClick}>Click me</Button>); fireEvent.click(screen.getByText('Click me')); expect(handleClick).toHaveBeenCalledTimes(1);});常用查询方法:getByText():通过文本查找元素getByRole():通过角色查找元素getByTestId():通过 data-testid 属性查找queryByText():查找元素,不存在时返回 nullfindByText():异步查找元素测试异步组件:test('loads and displays data', async () => { render(<UserList />); expect(screen.getByText('Loading...')).toBeInTheDocument(); await waitFor(() => { expect(screen.getByText('John')).toBeInTheDocument(); });});最佳实践:测试用户行为,而不是实现细节使用 @testing-library/react 而不是 enzyme使用 data-testid 作为最后的选择避免测试内部状态,测试可见输出保持测试简单和可读
阅读 0·2月19日 19:53

如何优化 Jest 测试性能?有哪些提高测试速度的方法?

优化 Jest 测试性能可以提高开发效率和 CI/CD 速度:1. 并行执行测试:Jest 默认并行运行测试,可以显著提高速度。确保测试之间相互独立。2. 选择性运行测试:# 只运行修改过的文件相关测试jest --onlyChanged# 只运行匹配模式的测试jest --testPathPattern=auth# 使用 .only 临时运行特定测试test.only('specific test', () => { /* ... */ });3. 优化测试环境:// jest.config.jsmodule.exports = { testEnvironment: 'node', // 比 jsdom 更快 maxWorkers: '50%', // 限制工作进程数量 testTimeout: 5000, // 设置合理的超时时间};4. 使用 Mock 减少外部依赖:jest.mock('./api', () => ({ fetchData: jest.fn(() => Promise.resolve('mocked data'))}));5. 优化覆盖率收集:collectCoverageFrom: [ 'src/**/*.{js,jsx,ts,tsx}', '!src/**/*.stories.{js,jsx,ts,tsx}', '!src/**/*.d.ts'],6. 缓存优化:Jest 自动缓存转换结果使用 --no-cache 禁用缓存(调试时)清理缓存:jest --clearCache7. 减少不必要的测试:避免过度测试跳过慢速测试:test.skip('slow test', () => { /* ... */ });使用 describe.skip 跳过整个测试套件8. 监听模式优化:# 使用 --watchAll 监听所有文件jest --watchAll# 使用 --watch 只监听相关文件jest --watch最佳实践:保持测试快速和独立使用 Mock 隔离外部依赖定期审查和优化慢速测试在 CI 中使用 --maxWorkers 控制资源使用
阅读 0·2月19日 19:27

如何在 Jest 中测试 Redux 相关代码?如何测试 Actions、Reducers 和 Selectors?

在 Jest 中测试 Redux 相关代码需要 Mock store 和 actions:1. 测试 Redux Actions:// actions.jsexport const increment = () => ({ type: 'INCREMENT' });export const addValue = (value) => ({ type: 'ADD_VALUE', payload: value });// actions.test.jsimport { increment, addValue } from './actions';describe('Actions', () => { test('creates increment action', () => { expect(increment()).toEqual({ type: 'INCREMENT' }); }); test('creates add value action', () => { expect(addValue(5)).toEqual({ type: 'ADD_VALUE', payload: 5 }); });});2. 测试 Redux Reducers:// reducer.jsconst initialState = { count: 0 };export default function counterReducer(state = initialState, action) { switch (action.type) { case 'INCREMENT': return { count: state.count + 1 }; case 'ADD_VALUE': return { count: state.count + action.payload }; default: return state; }}// reducer.test.jsimport counterReducer from './reducer';describe('Counter Reducer', () => { test('returns initial state', () => { expect(counterReducer(undefined, {})).toEqual({ count: 0 }); }); test('handles INCREMENT', () => { const state = counterReducer({ count: 0 }, { type: 'INCREMENT' }); expect(state).toEqual({ count: 1 }); });});3. 测试 Redux Selectors:// selectors.jsexport const selectCount = (state) => state.counter.count;// selectors.test.jsimport { selectCount } from './selectors';test('selects count from state', () => { const state = { counter: { count: 5 } }; expect(selectCount(state)).toBe(5);});4. 测试 Redux Thunks:// thunks.jsexport const fetchUser = (id) => async (dispatch) => { const response = await fetch(`/api/users/${id}`); const user = await response.json(); dispatch({ type: 'FETCH_USER_SUCCESS', payload: user });};// thunks.test.jsimport configureMockStore from 'redux-mock-store';import thunk from 'redux-thunk';import { fetchUser } from './thunks';const mockStore = configureMockStore([thunk]);test('fetches user successfully', async () => { global.fetch = jest.fn(() => Promise.resolve({ json: () => Promise.resolve({ id: 1, name: 'John' }) }) ); const expectedActions = [ { type: 'FETCH_USER_SUCCESS', payload: { id: 1, name: 'John' } } ]; const store = mockStore({}); await store.dispatch(fetchUser(1)); expect(store.getActions()).toEqual(expectedActions);});5. 测试 React-Redux 组件:import { render, screen } from '@testing-library/react';import { Provider } from 'react-redux';import Counter from './Counter';import { createStore } from 'redux';import reducer from './reducer';test('renders counter with initial state', () => { const store = createStore(reducer); render( <Provider store={store}> <Counter /> </Provider> ); expect(screen.getByText('Count: 0')).toBeInTheDocument();});最佳实践:单独测试 actions、reducers 和 selectors使用 redux-mock-store 测试异步 actionsMock API 调用以隔离测试测试组件时提供 mock store保持测试简单和独立避免测试 Redux 内部实现细节
阅读 0·2月19日 19:15

如何在 Jest 中测试 Vue 组件?如何使用 @vue/test-utils?

在 Jest 中测试 Vue 组件需要使用 @vue/test-utils:1. 安装依赖:npm install --save-dev @vue/test-utils jest vue-jest2. 配置 Jest:// jest.config.jsmodule.exports = { preset: '@vue/cli-plugin-unit-jest', moduleFileExtensions: ['js', 'json', 'vue'], transform: { '^.+\\.vue$': 'vue-jest', '^.+\\.js$': 'babel-jest', },};3. 测试 Vue 组件:import { mount } from '@vue/test-utils';import Counter from '@/components/Counter.vue';describe('Counter.vue', () => { test('renders initial count', () => { const wrapper = mount(Counter); expect(wrapper.text()).toContain('Count: 0'); }); test('increments count when button clicked', async () => { const wrapper = mount(Counter); const button = wrapper.find('button'); await button.trigger('click'); expect(wrapper.text()).toContain('Count: 1'); });});4. 测试 Props:test('renders with props', () => { const wrapper = mount(Counter, { propsData: { initialCount: 5 } }); expect(wrapper.text()).toContain('Count: 5');});5. 测试事件:test('emits increment event', async () => { const wrapper = mount(Counter); const button = wrapper.find('button'); await button.trigger('click'); expect(wrapper.emitted('increment')).toBeTruthy(); expect(wrapper.emitted('increment').length).toBe(1);});6. 测试计算属性:test('computes double count', () => { const wrapper = mount(Counter, { data() { return { count: 5 }; } }); expect(wrapper.vm.doubleCount).toBe(10);});7. 测试插槽:test('renders slot content', () => { const wrapper = mount(MyComponent, { slots: { default: 'Custom content' } }); expect(wrapper.text()).toContain('Custom content');});最佳实践:使用 mount 进行完整渲染,shallowMount 进行浅渲染测试用户交互和事件验证 props 和 emitted 事件测试计算属性和方法使用 setData 和 setProps 更新状态保持测试简单和可维护
阅读 0·2月19日 19:15