В документации библиотеки React Testing говорится, что не нужно выполнять очистку после каждого теста, но в документации renderHook
ничего не сказано, если unmount вызывается после завершения теста.
Так нужно ли вызывать unmount
в тестах с помощью renderHook
?
Вам не нужно вызывать функцию RTL очистки , когда вы используете renderHook() , из исходного кода мы знаем, что она вызывает функцию render с помощью <TestComponent/>
. Так
cleanup
вызывается автоматически после каждого теста по умолчанию, если используемая вами среда тестирования поддерживает глобальныйafterEach
(например, Mocha, Jest и Jasmine).
function renderHook(renderCallback, options = {}) {
const {initialProps, ...renderOptions} = options
if (renderOptions.legacyRoot && typeof ReactDOM.render !== 'function') {
const error = new Error(
'`legacyRoot: true` is not supported in this version of React. ' +
'If your app runs React 19 or later, you should remove this flag. ' +
'If your app runs React 18 or earlier, visit https://react.dev/blog/2022/03/08/react-18-upgrade-guide for upgrade instructions.',
)
Error.captureStackTrace(error, renderHook)
throw error
}
const result = React.createRef()
function TestComponent({renderCallbackProps}) {
const pendingResult = renderCallback(renderCallbackProps)
React.useEffect(() => {
result.current = pendingResult
})
return null
}
const {rerender: baseRerender, unmount} = render(
<TestComponent renderCallbackProps = {initialProps} />,
renderOptions,
)
function rerender(rerenderCallbackProps) {
return baseRerender(
<TestComponent renderCallbackProps = {rerenderCallbackProps} />,
)
}
return {result, rerender, unmount}
}
Если вы хотите протестировать логику кода в функции cleanup
хука useEffect()
, вам следует вызвать функцию ummount(). См. пример ниже:
import { renderHook, screen } from '@testing-library/react';
import React, { useEffect } from 'react';
describe('78435539', () => {
test('should pass', () => {
const Context = React.createContext('default');
function Wrapper({ children }) {
return (
<Context.Provider value = "provided">
<h1>Provider 1</h1>
{children}
</Context.Provider>
);
}
const { result } = renderHook(() => React.useContext(Context), { wrapper: Wrapper });
expect(result.current).toEqual('provided');
screen.debug();
});
test('should pass 2', () => {
const Context = React.createContext('default');
function Wrapper({ children }) {
return (
<Context.Provider value = "provided">
<h1>Provider 2</h1>
{children}
</Context.Provider>
);
}
const { result } = renderHook(() => React.useContext(Context), { wrapper: Wrapper });
expect(result.current).toEqual('provided');
screen.debug();
});
test('should pass 3', () => {
let count = 0;
const { unmount } = renderHook(() => {
useEffect(() => {
const onClick = () => {
count++;
};
document.body.addEventListener('click', onClick);
return () => {
document.body.removeEventListener('click', onClick);
};
}, []);
});
document.body.click();
expect(count).toBe(1);
unmount();
document.body.click();
expect(count).toBe(1);
});
});
Результат испытаний:
> jest -o
console.info
<body>
<div>
<h1>
Provider 1
</h1>
</div>
</body>
at logDOM (node_modules/@testing-library/dom/dist/pretty-dom.js:87:13)
console.info
<body>
<div>
<h1>
Provider 2
</h1>
</div>
</body>
at logDOM (node_modules/@testing-library/dom/dist/pretty-dom.js:87:13)
PASS stackoverflow/78435539/index.test.tsx
78435539
√ should pass (32 ms)
√ should pass 2 (5 ms)
√ should pass 3 (2 ms)
Test Suites: 1 passed, 1 total
Tests: 3 passed, 3 total
Snapshots: 0 total
Time: 1.044 s
Ran all test suites related to changed files.