Насмешка над вызовом метода API внутри componentDidMount - PullRequest
2 голосов
/ 06 марта 2020

Кто-нибудь получил совет о том, как провести модульное тестирование этого компонента? Я изо всех сил пытаюсь понять, как правильно смоделировать getFoo, а затем дождаться выполнения обещания, прежде чем запускать мои тесты. В настоящее время я использую Jest, чтобы попытаться сделать это.

import { getFoo } from "../../../api/fooApi";

class Accordion extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isActive: false,
      isLoaded: false
    };
  }

  componentDidMount() {
    getFoo(this.props.id).then(
      result => {
        this.setState({
          isLoaded: true,
          foo: result
        });
      },
      error => {
        this.setState({
          isLoaded: true,
          error
        });
      }
    );
  }

  render() {
    const { isActive, isLoaded, foo } = this.state;

    if (!isLoaded) return <Spinner />;

    return (
      <Accordion styled>
        <Accordion.Title
          active={isActive}
          onClick={() => {
            this.setState({ isActive: !isActive });
          }}
        >
          <Icon name="dropdown" />
          {foo}
        </Accordion.Title>
        <Accordion.Content active={isActive}>
          {foo}
        </Accordion.Content>
      </Accordion>
    );
  }
}

Это фактический метод.

export async function getFoo(id) {
  const res = await fetch(`/api/foo/${id}`);
  if (res.status !== 200) throw Error;
  return res.json();
}

1 Ответ

0 голосов
/ 06 марта 2020

Я бы использовал nock, он позволяет имитировать ответ API, вот пост, в котором подробно описано, как его использовать , это было бы что-то похожее на это:

...
import nock from 'nock'; 

it('renders without crashing', () => { 

   const scope = nock('http://myapi.com') 
   .get('/api/foo/')
   .reply(200, { products: [{ id: 1, name: 'nocked data' }] }, 
   { 
     'Access-Control-Allow-Origin': '*', 
     'Content-type': 'application/json' 
   }); 

   const div = document.createElement('div');
   ReactDOM.render(<ProductsList />, div);
   ReactDOM.unmountComponentAtNode(div); 
});
...