如何使用 React 测试库和 jest 测试 redux 状态更新
How to test redux state update with react testing library and jest
我正在尝试使用 jest 和 React 测试库编写测试,以查看商店是否更新状态以及组件内部是否显示新状态。
我有一个像这样的组件:
import { getName } from 'src/store/actions/hello/getName';
const HelloComponent = () => {
const dispatch = useDispatch();
const { name, isLoading } = useSelector((state:RootState) => state.Hello)
useEffect( () => {
dispatch(getName());
}, []);
return (
<div>
{ name &&
Hello {name}
}
</div>
)
}
有一家商店称 API 如:
const getName = () => (dispatch) => {
const URL = getUrl()
fetch(URL, {method: 'GET'})
.then((response) => response.json())
.then(({ data }) => dispatch({
type: 'SAVE_NAME',
payload: data.name
})) # This action updates the name inside the redux state
};
我正在使用 mswjs 来模拟 API 调用,我想在组件安装后进行测试,DOM 显示 'Hello John'。
这是我写的测试,但它不起作用:
it('shows the name', async () => {
const {findByText} = renderWithStore(<HelloComponent />);
expect(await findByText('Hello John')).toBeInTheDocument();
});
renderWithStore 模拟商店。
import configureStore from 'redux-mock-store';
import { render as rtlRender } from '@testing-library/react'
import { initialState as Hello } from '../src/store/reducers/helloReducer';
const mockStore = configureStore()
const initialStateMock = {
Hello
}
function render(
ui
) {
const store = mockStore(initialStateMock);
function Wrapper({ children }) {
return <Provider store={store}>{children}</Provider>
}
return rtlRender(ui, { wrapper: Wrapper })
}
好像没有等待状态更新。
非常感谢任何帮助
谢谢
我想我找到问题了。
redux-mock-store 库不允许测试状态变化。
内部组件正在更改“真实”商店状态而不是模拟商店状态,但它在渲染时使用的是模拟商店状态,但不会更改。
在这个测试中,我不需要传递一个不同于原来的初始存储,我可以使用“真实”存储而无需模拟它:
import {render} from '@testing-library/react'
import store from 'path_to_the_app_store_obj';
it('shows the name', async () => {
const {findByText} = render(
<Provider store={store}>
<HelloComponent />
</Provider>
);
expect(await findByText('Hello John')).toBeInTheDocument();
});
使用原始商店测试有效。
此外,有时您可能希望等待商店更改,在这些情况下,我发现添加:
await act(() => sleep(500));
在触发商店操作之后和“期待”之前。
我正在尝试使用 jest 和 React 测试库编写测试,以查看商店是否更新状态以及组件内部是否显示新状态。
我有一个像这样的组件:
import { getName } from 'src/store/actions/hello/getName';
const HelloComponent = () => {
const dispatch = useDispatch();
const { name, isLoading } = useSelector((state:RootState) => state.Hello)
useEffect( () => {
dispatch(getName());
}, []);
return (
<div>
{ name &&
Hello {name}
}
</div>
)
}
有一家商店称 API 如:
const getName = () => (dispatch) => {
const URL = getUrl()
fetch(URL, {method: 'GET'})
.then((response) => response.json())
.then(({ data }) => dispatch({
type: 'SAVE_NAME',
payload: data.name
})) # This action updates the name inside the redux state
};
我正在使用 mswjs 来模拟 API 调用,我想在组件安装后进行测试,DOM 显示 'Hello John'。
这是我写的测试,但它不起作用:
it('shows the name', async () => {
const {findByText} = renderWithStore(<HelloComponent />);
expect(await findByText('Hello John')).toBeInTheDocument();
});
renderWithStore 模拟商店。
import configureStore from 'redux-mock-store';
import { render as rtlRender } from '@testing-library/react'
import { initialState as Hello } from '../src/store/reducers/helloReducer';
const mockStore = configureStore()
const initialStateMock = {
Hello
}
function render(
ui
) {
const store = mockStore(initialStateMock);
function Wrapper({ children }) {
return <Provider store={store}>{children}</Provider>
}
return rtlRender(ui, { wrapper: Wrapper })
}
好像没有等待状态更新。
非常感谢任何帮助
谢谢
我想我找到问题了。
redux-mock-store 库不允许测试状态变化。 内部组件正在更改“真实”商店状态而不是模拟商店状态,但它在渲染时使用的是模拟商店状态,但不会更改。
在这个测试中,我不需要传递一个不同于原来的初始存储,我可以使用“真实”存储而无需模拟它:
import {render} from '@testing-library/react'
import store from 'path_to_the_app_store_obj';
it('shows the name', async () => {
const {findByText} = render(
<Provider store={store}>
<HelloComponent />
</Provider>
);
expect(await findByText('Hello John')).toBeInTheDocument();
});
使用原始商店测试有效。
此外,有时您可能希望等待商店更改,在这些情况下,我发现添加:
await act(() => sleep(500));
在触发商店操作之后和“期待”之前。