← Back to React Course | Chapter 12: Testing React Applications | Lesson 5 of 9

Custom Hooks की Testing

Hooks test करना ऐसा है जैसे एक recipe को अकेले test करना, पूरे restaurant से अलग, यह सुनिश्चित करने के लिए कि recipe खुद actually काम करती है।
Syntax
markup
import { renderHook, act } from "@testing-library/react";

const { result } = renderHook(() => useHookName(initial));

act(() => {
  result.current.action();
});
expect(result.current.value).toBe(expected);

आप एक Hook को Test में सीधे Call क्यों नहीं कर सकते

useState जैसे Hooks renders के बीच state track करने के लिए React की internal rendering machinery पर rely करते हैं — एक plain test function में सीधे useCounter() call करना एक error throw करता है, क्योंकि इसके hook करने के लिए कोई component या render cycle मौजूद नहीं।

Note: यह वही 'Rules of Hooks' restriction है जो हर जगह और apply होती है — hooks सिर्फ actual React rendering के अंदर काम करते हैं।
Warning: एक test file के top level में सीधे const result = useMyHook() की कोशिश करना हमेशा एक 'Invalid hook call' error के साथ fail होता है।

Isolation में Test करने के लिए renderHook उपयोग करना

@testing-library/react से renderHook() आपके hook को automatically एक minimal, invisible test component में wrap करता है, hook को एक real render cycle के अंदर run होने देते हुए। Returned result object की .current property आपको वह देती है जो hook ने return किया।

Note: renderHook specifically custom hooks test करने के लिए designed है बिना test के लिए सिर्फ उनके आस-पास एक real component बनाने की ज़रूरत के।
Warning: result.current hook की value reflect करता है उस समय जब आप इसे पढ़ते हैं — नई value देखने के लिए आपको किसी भी update के बाद इसे फिर पढ़ना होगा।

उदाहरण: Using renderHook to Test in Isolation

markup
// Run in your local React project (npm install required)
import { renderHook } from '@testing-library/react';

function useCounter() {
  const [count, setCount] = React.useState(0);
  return { count, increment: () => setCount(c => c + 1) };
}

test('counter starts at 0', () => {
  const { result } = renderHook(() => useCounter());
  expect(result.current.count).toBe(0);
});

⚠️ This example uses an npm package with no CDN build available here — run this in your local React project.

act() से Updates Trigger करना

Hook से returned एक function call करना (जैसे increment()) act() में wrap करना चाहिए, जो React को बताता है resulting state update को fully process करे और re-render करे आपके test के आगे जाने से पहले, यह सुनिश्चित करते हुए कि result.current latest value reflect करे।

Note: act() अक्सर newer testing-library versions द्वारा common cases के लिए automatically handle हो जाता है, लेकिन explicitly wrap करना हमेशा safe है।
Warning: एक state-updating call के आस-पास act() भूल जाना एक warning produce कर सकता है और, कुछ cases में, update actually apply होने से पहले result.current पढ़ सकता है।

उदाहरण: Triggering Updates with act()

markup
// Run in your local React project (npm install required)
import { renderHook, act } from '@testing-library/react';

function useCounter() {
  const [count, setCount] = React.useState(0);
  return { count, increment: () => setCount(c => c + 1) };
}

test('counter increments', () => {
  const { result } = renderHook(() => useCounter());
  act(() => { result.current.increment(); });
  expect(result.current.count).toBe(1);
});

⚠️ This example uses an npm package with no CDN build available here — run this in your local React project.

Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. किसी component के बाहर एक test function body में सीधे एक hook call करने की कोशिश करना — hooks सिर्फ React के rendering system के अंदर run हो सकते हैं।
  2. यह भूल जाना कि renderHook के act() calls के अंदर state updates को React द्वारा correctly process होने के लिए wrap किया जाना चाहिए।
  3. एक hook को completely isolation में test करना जब इसका real behavior सिर्फ एक specific component context के साथ combined होने पर sense बनाता है।
चैप्टर सारांश
  • Hooks को directly एक test में call नहीं किया जा सकता — उन्हें React के render cycle के अंदर run होना चाहिए।
  • @testing-library/react से renderHook() एक hook को automatically एक minimal test component में wrap करता है।
  • result object की .current property hook के return किए गए को access देती है।
  • act() यह सुनिश्चित करता है कि एक test के दौरान trigger हुए state updates assertions run होने से पहले fully process हो चुके हों।
ब्राउज़र सपोर्ट

npm install @testing-library/react चाहिए — एक Node test environment में run होता है, इस browser sandbox में नहीं।

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.