使用来自 redux 的数据动态呈现的测试按钮

Testing buttons in react dynamically rendered with data from redux

这是我做的一个简化示例。

我有以下反应组件

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
  
});

我怎样才能做到这一点?

请看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();
}

对于更多的“集成”测试,您还可以从最终填充状态的函数中模拟 return 值,例如取电话。这样,您就不需要创建 preloadedState 而是模拟获取调用,您将使用其对象进行断言。