使用来自 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
而是模拟获取调用,您将使用其对象进行断言。
这是我做的一个简化示例。
我有以下反应组件
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
而是模拟获取调用,您将使用其对象进行断言。