αƞjiβ
αƞjiβ

Reputation: 3256

Testing child component props after parent update state using set

I have a following functional component which send some filtered data to the child component. Code is working fine i.e I can run app and see the components being render with right data. But the test I have written below is failing for ChildComponent. Instead of getting single array element with filtered value it is getting all three original values. I am confused as similar test for FilterInputBox component for props filterValue is passing. Both tests are checking the updated props value after same event filter input change i.e handleFilterChange. Am I missing anything? Any suggestion?

Source Code

function RootPage(props) {
  const [filterValue, setFilterValue] = useState(undefined);
  const [originalData, setOriginalData] = useState(undefined);
  const [filteredData, setFilteredData] = useState(undefined);

  const doFilter = () => {
    // do something and return some value
  }

  const handleFilterChange =  (value) => { 
    const filteredData = originalData && originalData.filter(doFilter);  
    setFilteredData(filteredData);        
    setFilterValue(value);
  };

  React.useEffect(() => {
    async function fetchData() {
        await myService.fetchOriginalData()
            .then((res) => {
                setOriginalData(res);                    
            })
    }

    fetchData();

  }, [props.someFlag]);

  return (
    <>
        <FilterInputBox
            filterValue={filterValue}
            onChange={handleFilterChange}
        />
        <ChildComponent
            data={filteredData}
        />
    </>
  );
}

Test Code

describe('RootPage', () => {
  let props,
    fetchOriginalDataStub,
    useEffectStub,
    originalData;

  const flushPromises = () => new Promise((resolve) => setImmediate(resolve));

  beforeEach(() => {
    originalData = [
        { name: 'Brown Fox' },
        { name: 'Lazy Dog' },
        { name: 'Mad Monkey' }
    ];
    fetchOriginalDataStub = sinon.stub(myService, 'fetchOriginalData').resolves(originalData);
    useEffectStub = sinon.stub(React, 'useEffect');
    useEffectStub.onCall(0).callsFake((f) => f());
    props = { ... };            
  });

  afterEach(() => {
    sinon.restore();
  });

  it('should send filtered data', async () => {
    const renderedElement = enzyme.shallow(<RootPage {...props}/>);
    const filterBoxElement = renderedElement.find(FilterInputBox);;

    await flushPromises();
    filterBoxElement.props().onChange('Lazy');
    await flushPromises();

    //This "filterValue" test is passing
    const filterBoxWithNewValue = renderedElement.find(FilterInputBox);
    expect(filterBoxWithNewValue.props().filterValue).to.equal('Lazy'); 

    //This "data" test is failing
    const childElement = renderedElement.find(ChildComponent);
    expect(childElement.props()).to.eql({
      data: [
          { name: 'Lazy Dog' }
      ]
    });
  });        
});

UPDATE After putting some log statements I am seeing that when I am calling onChange originalData is coming undefined. Not sure why that is happening that seems to be the issue.

Still looking for help if anyone have any insight on this.

Upvotes: 0

Views: 512

Answers (0)

Related Questions