如何在 Jest 中测试 redux 选择器?
Posted
技术标签:
【中文标题】如何在 Jest 中测试 redux 选择器?【英文标题】:How to test redux selector in Jest? 【发布时间】:2020-11-28 16:31:53 【问题描述】:我想测试以下选择器:
export const getApp = (): IApp | null =>
return useSelector<IState, IApp | null>((state) => state.appState.app);
;
这是测试:
import appSelectors, getApp from '../appSelectors';
import thunk from 'redux-thunk';
import IApp from '...common...interfaces';
let store: any = null;
const middlewares = [thunk];
const mockStore = configureMockStore(middlewares);
const createMockStore = () =>
store = mockStore(testsStore.initialState);
;
describe('apps selectors', () =>
test('getApp', () =>
const mockedApp: IApp =
id: 'mocked_id',
name: 'mocked_id',
;
// ... >> modify the testsStore.initialState here ...
createMockStore();
expect(getApp()).toEqual(mockedApp);
);
);
这是我得到的错误: 无效的挂钩调用。钩子只能在函数组件的主体内部调用。这可能发生
for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
7 |
8 | export const getApp = (): IApp | null =>
> 9 | return useSelector<IState, IApp | null>((state) => state.appState.app);
| ^
10 | ;
如何测试这个选择器?
谢谢。
【问题讨论】:
你使用测试框架吗?使用它来渲染组件。你不能调用它,因为它不是一个常规函数。 @EstusFlask,测试选择器的唯一方法是使用组件??我正在使用 Jest/Enzym。所以,为此,我也可以使用虚拟组件,对吧?是否会考虑覆盖此类测试?谢谢。 您可以在组件外部公开(state) => state.appState.app
选择器函数,以便与 React 部分分开重用或测试。 useSelector
钩子应该在组件内部调用。 getApp
就是所谓的自定义钩子,是的,它需要用 dummy 组件进行测试。
好的,虚拟组件将被创建 - 我如何测试选择器的返回值?它是一个功能组件 - 无法测试其中的任何状态/值...
【参考方案1】:
(state) => state.appState.app
函数是一个选择器,可以单独提取和测试,但由于简单,可以和getApp
一起测试。
getApp
和 useSelector
是 custom hooks,它们应该被 React 渲染器调用而不是直接调用。这需要使用虚拟组件来完成。由于开发人员可以完全控制它,因此需要将值格式化并转换为布局,以便可以明确断言:
const Dummy = () =>
const app = getApp();
return <div>
<div data-testid="app-id">app.id</div>
<div data-testid="app-name">app.name</div>
</div>;
;
const wrapper = mount(<Dummy/>);
expect(wrapper.find('[data-testid="app-id"]').text()).toBe('mocked id');
expect(wrapper.find('[data-testid="app-name"]').text()).toBe('mocked name');
其中data-testid
属性是其他测试库使用的约定,尤其是适合这种灰盒测试的Testing Library。
【讨论】:
答案应该显示如何测试选择器 应该吗?答案很明确,(state) => state.appState.app 函数是一个选择器,可以单独提取和测试,但由于简单,可以和getApp一起测试 .更清楚地说,useSelector 钩子中的选择器不能直接测试,它需要重构代码才能做到这一点。如果您对帖子有特定的困难,您可以询问它。感谢您的投票。 感谢您的详细回答,埃斯图斯。您是否尝试过使用resultFunc
单独测试选择器?以上是关于如何在 Jest 中测试 redux 选择器?的主要内容,如果未能解决你的问题,请参考以下文章
如何测试从 mapDispatchToProps 传递的函数(React/Redux/Enzyme/Jest)
Jest/Enzyme 单元测试:如何将存储传递给使用 redux 4 和 react-redux 6 连接功能的浅层组件
如何测试 Redux 的 dispatch() 是不是已在 React Component (Jest + Enzyme) 中被调用
如何使用 redux-saga-test-plan 测试选择器功能
如何使用 Jest 和 Enzyme 测试具有 Router、Redux 和两个 HOC 的 React 组件?
Redux Saga:使用 redux-saga-test-plan 和 jest 在我的 saga 中测试纯 javascript 函数