【问题标题】:How to test redux state update with react testing library and jest如何使用反应测试库和笑话测试 redux 状态更新
【发布时间】:2021-01-13 08:26:21
【问题描述】:

我正在尝试使用 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 })
}

它似乎没有等待状态更新。

非常感谢任何帮助

谢谢

【问题讨论】:

  • 你的renderWithStore(&lt;HelloComponent /&gt;)函数是什么?可以展示一下吗?
  • 你需要展示如何导入getName()函数
  • 您是否想过单独测试存储(操作),然后仅在您的操作调用dispatch 的情况下进行组件化? (模拟动作函数和useDispatch钩子)
  • 如果我的解决方案不可行,我会尝试一下。但如果可能的话,我宁愿避免嘲笑,以使测试更加“现实”。在这里,我只用 mswjs 模拟 API 调用。此外,我想测试用户看到的内容,而不是对操作代码进行单元测试。

标签: javascript reactjs redux jestjs react-testing-library


【解决方案1】:

我想我找到了问题所在。

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

在触发存储操作之后和“预期”之前。

【讨论】:

    猜你喜欢
    • 2021-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-25
    相关资源
    最近更新 更多