Jest.js 如何测试UI根据useEffect钩子中的异步调用而改变的react原生组件

kmb7vmvb  于 2023-08-01  发布在  Jest
关注(0)|答案(2)|浏览(144)

我有一个react native组件OrdersScreen,我无法测试,因为组件在setState时更新:setRenderLoader(false)在React.useEffect()钩子中被调用。

const OrdersScreen = ({ navigation }) => {
  let [renderLoader, setRenderLoader] = React.useState(true);
  let [ordersInfo, setOrdersInfo] = React.useState([]);
  React.useEffect(() => {
    ordersController.getOrdersForAgent() // some API call
      .then((res) => {
        console.log("getOrdersForAgent res", res);
        setOrdersInfo(res);
        if (res)
          res.forEach(ord => dispatch(addOrder(ord)));
        setRenderLoader(false);
      })
      .catch((err) => {
        console.log("getOrdersForAgent err", err);
      });
  }, []);
return (
    <View
      style={ordersScreenStyle.container}>
      {renderLoader
        ?
        (<Loader />)
        :
        (<SectionList
          ...
        />)}
    </View>

字符串
下面是我的测试代码:

import renderer from 'react-test-renderer';
import {act} from 'react-test-renderer'

describe('<OrdersScreen/>', () => {
    test('Verify order item', async () => {
        const ORDER_ITEMS = DEFAULT_VALUE;
        ordersController.getOrdersForAgent = jest.fn(() => Promise.resolve(ORDER_ITEMS));
        const setRenderLoader = jest.fn();

        let component;
        await act(async () => {
            //render with redux just wraps renderer.create(component) with a redux store
            component = await renderWithRedux(<OrdersScreen />);
        })
        const root = component.root;
        let tree = component.toJSON();
        console.log('tree', tree);
        if (store.getState().ordersReducer.length === 0) {
            expect(setRenderLoader).not.toHaveBeenCalled();
        }
        else {
            expect(setRenderLoader).not.toHaveBeenCalledWith(false);
        }


    })
})


我得到下面的错误:

Consider adding an error boundary to your tree to customize error handling behavior.
    Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.

      142 |         if (res)
      143 |           res.forEach(ord => dispatch(addOrder(ord)));
    > 144 |         setRenderLoader(false);


有没有人能给予点提示,说明如何测试这个组件?我对这方面很陌生。任何帮助都是感激的。

ujv3wf0j

ujv3wf0j1#

如果dispatch(addOrder(ord))async,那么您希望在for..of循环中处理这些操作,而不是forEach
forEach循环的行为与for循环不同,而for循环await在进一步移动之前执行迭代,forEach循环同时执行所有迭代。

for (const ord of res){
 dispatch(addOrder(ord))
}

字符串

enxuqcxy

enxuqcxy2#

import "./App.css";

function App() {
    let [renderLoader, setRenderLoader] = React.useState(true);
  let [ordersInfo, setOrdersInfo] = React.useState([]);
useEffect(() => {
    ordersController?.getOrdersForAgent() // some API call
      .then((res) => {
        console.log("getOrdersForAgent res", res);
        setOrdersInfo(res);
        if (res)
          res?.forEach(ord => dispatch(addOrder(ord)));
        setRenderLoader(false);
      })
      .catch((err) => {
        console.log("getOrdersForAgent err", err);
      });
  }, []);
  return (
    <div className="App">
      <header className="App-header">
        <img src="/logo.svg" className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.jsx</code> and save to reload! :)
        </p>
        <span className="App-link">Hello from codedamn :)</span>
      </header>
    </div>
  );
}

export default App;

字符串
尝试使用此代码在这里我只得到ordersController未导入错误

相关问题