使用renderHook测试钩子

时间:2019-12-22 07:39:55

标签: reactjs react-hooks react-hooks-testing-library

我想测试一个自定义的钩子,该钩子是作为帮助功能与其他钩子一起重用的。它在实现中正在调用useDispatchuseSelector,并将数据保存在会话存储中:

 export function useCustomHook(key, obj)
  {
    let myObject = {
      somefield: obj.someField
    };
    sessionStorage.setItem(key, JSON.stringify(myObject));
    const dispatch = useDispatch();
    dispatch(actionCreator.addAction(key, myObject));
  }

测试:

it('should have data in redux and session storage', () =>
{
  const obj = { 
    somefield: 'my val', 
  };
  renderHook(() => useCustomHook('some key', obj));
  let savedObj= JSON.parse(sessionStorage.getItem('some key'));
  expect(savedObj.someField).toBe('my val');
  renderHook(() => 
  {
    console.log("INSIDE");
    let reduxObj = useSelector(state => state.vals);
    console.log("THE OBJECT: " );
    console.log(reduxObj);
    expect(reduxObj).toBe(2); //just to see if it fails the test - it's not
  });
})

无论我尝试什么,测试只会到达“ INSIDE”控制台日志,而不会打印“ THE OBJECT:”控制台日志。测试本身仍然通过,因此就像useSelector以某种方式停止了其余renderHook执行。

我猜这与测试没有连接商店这一事实有关...在这种情况下,可以做些什么来测试redux?

1 个答案:

答案 0 :(得分:0)

您需要提供a wrapper component,并在Redux Provider上添加一个store才能连接:

it('should have data in redux and session storage', () =>
{
  const obj = { 
    somefield: 'my val', 
  };

  const store = {} // create/mock a store
  const wrapper = ({ children }) => <Provider store={store}>{children}</Provider>

  renderHook(() => useCustomHook('some key', obj), { wrapper });
  let savedObj= JSON.parse(sessionStorage.getItem('some key'));
  expect(savedObj.someField).toBe('my val');
  renderHook(() => {
    console.log("INSIDE");
    let reduxObj = useSelector(state => state.vals);
    console.log("THE OBJECT: " );
    console.log(reduxObj);
    expect(reduxObj).toBe(2); //just to see if it fails the test - it's not
  }, { wrapper });
})

作为一个旁注,renderHook捕获了错误,这就是为什么您在测试中看不到它们的原因,如果您尝试访问result.current则会抛出该错误,并且您可能已经看到它用result.error表示,但是这里不从要声明的自定义钩子返回值的用法很不常见。

这可能还会通过在第二个renderHook调用中使用断言来引起问题。您可能想要从挂钩返回值并在外部声明,或者在Redux存储中声明更新的值。