skip to Main Content

I have a react native component OrdersScreen which I am not able to test because the component gets updated when setState : setRenderLoader(false) is called in React.useEffect() hook.

  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>

Below is the test code I have:

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



    })
})

I get the below error:

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

Could anyone please give pointers as to how this component is to be tested? I am quite new to this. Any help is appreciated.

2

Answers


  1. Have you tried creating a separate function and then call that function in hook….this

      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);
          });
      }, []);

    to this

      const getAgentOrders=()=>{
          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);
          });
          
          }
      
      React.useEffect(() => {
         getAgentOrders()
      }, []);
    Login or Signup to reply.
  2. If dispatch(addOrder(ord)) is async then you want to handle those actions inside a for..of loop instead of forEach.

    The forEach loop acts differently than the for loop, while the for loop await the iteration before moving further, the forEach loop executes all of the iterations simultaneously.

    for (const ord of res){
     dispatch(addOrder(ord))
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search