【问题标题】:Testing buttons in react dynamically rendered with data from redux使用来自 redux 的数据动态呈现反应中的测试按钮
【发布时间】:2022-01-06 12:00:48
【问题描述】:

这是我制作的一个简化示例。

我有以下反应组件

Test.tsx

import * as React from 'react';
import { useEffect } from 'react';
import { useAppDispatch, useAppSelector } from '../app/hooks';
import { selectTest, setTest } from './testslice';

const Test: React.FunctionComponent = (props) => {

    const vals = useAppSelector(selectTest)
    const dispatch = useAppDispatch()

    useEffect(() => {
      dispatch(setTest(["2","3","4","5"]))
    },[])

  return <>
    {vals.map((v,i) => <button key={i}>{v}</button>)}
  </>;
};

export default Test;

还有下面的redux reducer slice

testSlice.ts

import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { RootState } from "../app/store";

export interface AppState {
  test:string[]
}

const initialState: AppState = {
  test:[]
};



export const appSlice = createSlice({
  name: 'test',
  initialState,
  reducers: {
    setTest(state,action: PayloadAction<string[]>) {
        state.test = action.payload
    }
  },
});

export const {
  setTest,
} = appSlice.actions;

export const selectTest = (state: RootState) => state.test.test;


export default appSlice.reducer;

我想测试Test 组件并查看按钮是否使用我发送到redux 存储的值呈现(值的长度将是固定长度)

Test.test.tsx

import React from 'react';
import { render } from '@testing-library/react';
import { Provider } from 'react-redux';



import { store } from '../app/store';
import Test from './TestComponent';

test('renders learn react link', () => {
  const { getByText } = render(
    <Provider store={store}>
      <Test/>
    </Provider>
  );

//Somehow test that the buttons rendered in <Test/> component have the values dispatched in the useEffect hook
  
});

我怎样才能做到这一点?

【问题讨论】:

  • 你试过什么?您是否尝试过 expect(getByText('1')).toBeTruthy() (每个值都相同)?

标签: reactjs redux react-testing-library


【解决方案1】:

请查看official documentation of testing redux with react and testing library。这个想法是创建一个preloadedState,它从测试内部注入到您的应用程序中。然后您可以测试此preloadedState 的对象并查看对象是否正确呈现。在上面的文档中设置辅助渲染功能后,例如

...
import appReducer from 'PATH/testSlice';
...
store = configureStore({ reducer: { test: appReducer }, preloadedState })

你可以这样做:

...
import { render } from '../../test-utils'
...
const givenState = { test: ["1", "2", "3"] }
const { getByText } = render( <Test/>, { preloadedState: givenState });
for(const val of givenState.test) {
   expect(getByText(val).toBeVisible();
}

对于更多“集成”测试,您还可以模拟最终填充状态的函数的返回值,例如接电话。这样,您无需创建 preloadedState 而是模拟 fetch 调用,您可以将其对象用于断言。

【讨论】:

  • 我也意识到,我可以在测试中直接调用store.getState(),但不知道这是否是最好的方法。
  • 这取决于您要准确测试的内容。如果您在不直接提供道具的情况下停留在更多的单元测试级别,您可能会模拟并访问存储/状态。但是,如果您想测试与 store 的集成并因此也测试 reducer,则不能直接访问状态。然后你可以模拟数据源,例如预期会被执行的网络请求。
猜你喜欢
  • 2018-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-20
  • 2021-10-23
  • 2016-03-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多