> For the complete documentation index, see [llms.txt](https://notes.lirenxn.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://notes.lirenxn.com/2020/wk-notes-01-23-test-hook.md).

# Wk-notes-01-23-test-hook

### Bugs from analytic tools

There could be bugs triggered from other lib, like analytics tool glass box. Do **NOT** spend too much time on it.

### Test React Hooks

I invested some time into hooks recently, this is sth I want to share: People says, for **custom hooks,** it can extract same functionality out as **composable logic,** so that the logic is more maintainable and **testable**，but then I found to test it, you will **always** need to create and mount a `Component` over it, because hooks behavior happens ONLY in react component in the vdom. **I would say it is testable, but still a bit painful.**

So here are 2 snippets I found that can be a conventions we used to test a custom hook:

**I.** With Customed Component, and simply get things from wrapper.prop

```javascript
it('get same value when using `useMemo` and rerender with same prop in dependencies', () => {
      function Child() {
        return false;
      }
      function ComponentUsingMemoHook(props) {
        const { count } = props;
        const memoized = useMemo(() => ({ result: count * 2 }), [count]);
        return (
          <Child memoized={memoized} />
        );
      }
      const wrapper = mount(<ComponentUsingMemoHook count={1} />);
      const initialValue = wrapper.find(Child).prop('memoized');
      wrapper.setProps({ unRelatedProp: '123' });
      const nextValue = wrapper.find(Child).prop('memoized');
      expect(initialValue).to.equal(nextValue);
    });
    it('get different value when using `useMemo` and rerender with different prop in dependencies', () => {
      function Child() {
        return false;
      }
      function ComponentUsingMemoHook(props) {
        const { count, relatedProp } = props;
        const memoized = useMemo(() => ({ result: count * 2 }), [count, relatedProp]);
        return (
          <Child memoized={memoized} relatedProp={relatedProp} />
        );
      }
      const wrapper = mount(<ComponentUsingMemoHook relatedProp="456" count={1} />);
      const initialValue = wrapper.find(Child).prop('memoized');
      wrapper.setProps({ relatedProp: '123' });
      const nextValue = wrapper.find(Child).prop('memoized');
      expect(initialValue).to.not.equal(nextValue);
    });
  });   
});
```

**Ref :** <https://github.com/airbnb/enzyme/pull/2144/files#diff-fadeaaf857f5b3fe6522e89a63ca9a41>

**II.** Use react-test-hooks lib

```
const { result } = renderHook(() => useTime(100));       expect(result.current).toBe('mockNow');
```

**Ref :** <https://www.newline.co/@jamesfulford/testing-custom-react-hooks-with-jest--8372a502>

### **A practice from downshiftjs**

* Get a folder/file structure for each complex hook
* Use a testUtil to set up **rendering a test component** (as always)
* Focus on testing hooks funtionality in test.spec.js

**Ref :** <https://github.com/downshift-js/downshift/blob/v4.0.8/src/hooks/useSelect/testUtils.js>, <https://github.com/downshift-js/downshift/blob/v4.0.8/src/hooks/useSelect/__tests__/getLabelProps.test.js>
