您可以使用jest.mock()
来模拟next/router
模块、useRouter
钩子及其返回值。在我们改变query
值之后,我们应该调用rerender函数来重新渲染自定义的钩子,这样useEffect
钩子就会使用新query
的作为它的依赖。
此外,我使用jest.spyOn()
添加 spy onconsole.count()
方法来检查effect
函数调用的次数。
例如
useCustomHook.ts
:
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
export function useCustomHook() {
const { query } = useRouter();
const [state, setState] = useState({});
useEffect(() => {
console.count('effect');
setState({ id: query.id });
}, [query]);
return state;
}
useCustomHook.test.ts
:
import { useRouter } from 'next/router';
import { renderHook } from '@testing-library/react-hooks';
import { useCustomHook } from './useCustomHook';
import { mocked } from 'ts-jest/utils';
import { NextRouter } from 'next/dist/next-server/lib/router/router';
jest.mock('next/router');
const useMockRouter = mocked(useRouter);
describe('68660313', () => {
test('should pass', () => {
const countSpy = jest.spyOn(console, 'count');
const query1 = ({ query: { id: '1' } } as unknown) as NextRouter;
const query2 = ({ query: { id: '2' } } as unknown) as NextRouter;
useMockRouter.mockReturnValue(query1);
const { result, rerender } = renderHook(() => useCustomHook());
expect(result.current).toEqual({ id: '1' });
useMockRouter.mockReturnValue(query2);
rerender();
expect(result.current).toEqual({ id: '2' });
expect(countSpy).toBeCalledTimes(2);
});
});
测试结果:
PASS examples/68660313/useCustomHook.test.ts (7.664 s)
68660313
✓ should pass (32 ms)
console.count
effect: 1
at console.<anonymous> (node_modules/jest-environment-enzyme/node_modules/jest-mock/build/index.js:866:25)
console.count
effect: 2
at console.<anonymous> (node_modules/jest-environment-enzyme/node_modules/jest-mock/build/index.js:866:25)
------------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
------------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
useCustomHook.ts | 100 | 100 | 100 | 100 |
------------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 8.184 s
包的版本:
"next": "^11.0.1",
"jest": "^26.6.3",
"ts-jest": "^26.4.4",
"react": "^16.14.0",