2

How do you test a component (say <Person /> in this case) if it renders fully but only after <Loading /> completes, which is after a successful Ajax call?

I am using Jest and Enzyme. With Enzyme, however, the snapshot would be of Person with the Loading component and not the final, rendered state after the Ajax call. I would need to mock my Ajax call, but what would that look like with a mock and then taking a Snapshot after?

class Person extends Component {
...
   componentWillMount() {
     // ajax call to person data, including ID
     // on successful Ajax completion, set state.personID and other values, etc. 

     axios.get('.../person', {
      params: {
        AltID: 12345
        }
     }).then(function (response) {
      this.setState({personID: response.data.personID,...});

     }).catch(function (error) {
      ...
     });
   }

    render() {
      if (!this.state.personID) {
        return (
          <div className="App">
            <Loader />
          </div>);
      }
      return (
        <div className="App">
          ...
          Person ID: {{this.state.personID}}
          ...
        </div>
      );
    }
}

Enzyme snapshot test (needs embellishing):

describe('Person', () => {
  it('renders correctly', () => {
    const rendered = renderer.create(<Person />);
    expect(rendered.toJSON()).toMatchSnapshot();
  });
});

Lastly, a work around such as setting this.setState({personID: value}) in the test is not what I would be looking for, since, in the real unpublished scenario, componentWillMount performs an Ajax call to authenticate the users. Currently, that's getting pushed to an error page.

doelleri
  • 19,232
  • 5
  • 61
  • 65
user1322092
  • 4,020
  • 7
  • 35
  • 52

1 Answers1

0

You can mock api calls https://facebook.github.io/jest/docs/en/tutorial-async.html or you can just make 2 tests, one with the condition being True, and the other with the condition being False. Your api call just changes the state from one state to another so...you need to test if everything renders correctly, according to the state.

Example:

test('the data is peanut butter', done => {
  function callback(data) {
    expect(data).toBe('peanut butter');
    done();
  }W

  fetchData(callback);
});
João Vilaça
  • 601
  • 1
  • 6
  • 13
  • thanks for the tip. However, could you put together a snippet or pseudo code I could try testing? I imagine that would be helpful to others who are looking for a definitive solution or example to reference. Furthermore, that will also help with upvoting your answer by others... – user1322092 Nov 05 '17 at 19:37
  • There are plenty of examples in the link I posted. But honestly, U can just test if the render matches your condition, like...if you have personID it would render X, if not...it would render Y. Either way, you can just go to that link, and do exactly as it's there to test your async function. – João Vilaça Nov 06 '17 at 13:07
  • 2
    Thanks... but how do you mock the component's API call in Jest, without circumventing the component, such as setting the state property (`this.setState({personID: value})`)? In the docs you shared, it shows mocking first-class API calls (separate file), but what about ones in the component, such as the call in `componentWillMount` (or say `Person.userAuthorized`, which doesn't use data in the response, but rather 200 http response code? – user1322092 Nov 09 '17 at 03:59