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

面试题手册

Jest 中有哪些测试匹配器(Matchers)?如何使用自定义匹配器?

Jest 提供了多种测试匹配器(Matchers)来验证不同的条件:相等性匹配器:toBe(value):严格相等(===)toEqual(value):深度相等toStrictEqual(value):严格深度相等(包括 undefined 属性)toMatchObject(object):部分匹配对象真值匹配器:toBeNull():只匹配 nulltoBeUndefined():只匹配 undefinedtoBeDefined():非 undefinedtoBeTruthy():真值toBeFalsy():假值数字匹配器:toBeGreaterThan(number):大于toBeGreaterThanOrEqual(number):大于等于toBeLessThan(number):小于toBeLessThanOrEqual(number):小于等于toBeCloseTo(number, precision):浮点数近似相等字符串匹配器:toMatch(regexp | string):匹配正则或字符串toContain(item):包含元素或子字符串数组匹配器:toContain(item):包含元素toContainEqual(item):包含相等元素toHaveLength(number):数组长度toBeArray():是数组对象匹配器:toHaveProperty(keyPath, value):有特定属性toMatchObject(object):部分匹配对象函数匹配器:toHaveBeenCalled():被调用toHaveBeenCalledWith(...args):用特定参数调用toHaveBeenCalledTimes(n):调用次数toHaveReturned():返回值toHaveReturnedWith(value):返回特定值异常匹配器:toThrow(error?):抛出错误toThrowErrorMatchingSnapshot():错误快照自定义匹配器:expect.extend({ toBeWithinRange(received, floor, ceiling) { const pass = received >= floor && received <= ceiling; return { pass, message: () => pass ? `expected ${received} not to be within range ${floor}-${ceiling}` : `expected ${received} to be within range ${floor}-${ceiling}` }; }});test('number within range', () => { expect(100).toBeWithinRange(90, 110);});否定匹配器:所有匹配器都可以使用 .not 进行否定:expect(value).not.toBe(42);expect(array).not.toContain('item');
阅读 0·2月21日 15:57

如何在 Jest 中测试 React Hooks?如何使用 renderHook 和 act?

Jest 提供了多种测试 React Hooks 的方法,主要使用 @testing-library/react-hooks:1. 测试 useState:import { renderHook, act } from '@testing-library/react-hooks';test('useState hook', () => { const { result } = renderHook(() => useCounter(0)); expect(result.current.count).toBe(0); act(() => { result.current.increment(); }); expect(result.current.count).toBe(1);});2. 测试 useEffect:test('useEffect hook', () => { const { result } = renderHook(() => useFetch('/api/data')); expect(result.current.loading).toBe(true); await act(async () => { await waitFor(() => !result.current.loading); }); expect(result.current.data).toBeDefined();});3. 测试 useContext:test('useContext hook', () => { const wrapper = ({ children }) => ( <ThemeContext.Provider value="dark"> {children} </ThemeContext.Provider> ); const { result } = renderHook(() => useTheme(), { wrapper }); expect(result.current.theme).toBe('dark');});4. 测试自定义 Hook:function useCustomHook(initialValue) { const [value, setValue] = useState(initialValue); const double = useMemo(() => value * 2, [value]); return { value, setValue, double };}test('custom hook', () => { const { result } = renderHook(() => useCustomHook(5)); expect(result.current.value).toBe(5); expect(result.current.double).toBe(10); act(() => { result.current.setValue(10); }); expect(result.current.double).toBe(20);});5. 测试异步 Hook:test('async hook', async () => { const { result, waitForNextUpdate } = renderHook(() => useAsyncData()); expect(result.current.loading).toBe(true); await waitForNextUpdate(); expect(result.current.loading).toBe(false); expect(result.current.data).toBeDefined();});6. 测试错误处理:test('hook error handling', async () => { const { result, waitForNextUpdate } = renderHook(() => useFetch('/invalid')); await waitForNextUpdate(); expect(result.current.error).toBeInstanceOf(Error);});最佳实践:使用 renderHook 测试 Hook使用 act 包装状态更新测试 Hook 的初始状态和更新后的状态测试异步 Hook 时使用 waitFor 或 waitForNextUpdate测试错误边界情况保持测试简单,专注于 Hook 的行为
阅读 0·2月21日 15:57

如何在 Jest 中进行参数化测试?如何使用 test.each 和 describe.each?

Jest 提供了参数化测试的方法,可以使用 test.each 或 describe.each 来运行多组测试数据:1. 使用 test.each 进行参数化测试:test.each([ [1, 1, 2], [1, 2, 3], [2, 1, 3],])('adds %i + %i = %i', (a, b, expected) => { expect(add(a, b)).toBe(expected);});2. 使用对象数组:test.each([ { a: 1, b: 1, expected: 2 }, { a: 1, b: 2, expected: 3 }, { a: 2, b: 1, expected: 3 },])('$a + $b = $expected', ({ a, b, expected }) => { expect(add(a, b)).toBe(expected);});3. 使用 describe.each 进行分组测试:describe.each([ ['node', 'node'], ['jsdom', 'browser'],])('test environment: %s', (env, type) => { test(`runs in ${type} environment`, () => { expect(process.env.NODE_ENV).toBeDefined(); });});4. 测试表格数据:test.each` a | b | expected ${1} | ${1} | ${2} ${1} | ${2} | ${3} ${2} | ${1} | ${3}`('returns $expected when $a is added to $b', ({ a, b, expected }) => { expect(add(a, b)).toBe(expected);});5. 测试边界情况:test.each([ [0, 0, 0], [Number.MAX_SAFE_INTEGER, 1, Number.MAX_SAFE_INTEGER + 1], [Number.MIN_SAFE_INTEGER, -1, Number.MIN_SAFE_INTEGER - 1],])('handles edge cases: %i + %i = %i', (a, b, expected) => { expect(add(a, b)).toBe(expected);});6. 测试错误情况:test.each([ [undefined, 'input is required'], [null, 'input is required'], ['', 'input cannot be empty'],])('throws error for invalid input: %p', (input, expectedError) => { expect(() => validate(input)).toThrow(expectedError);});最佳实践:使用参数化测试减少重复代码清晰描述测试数据和预期结果测试正常情况和边界情况使用表格格式提高可读性保持测试数据简洁明了
阅读 0·2月21日 15:57