APIのhttp://localhost:3001/api/cards
からコンポーネントのcomponentDidMount関数からGET要求を出しています。これにより、コンポーネントが初めてレンダリングされた後にのみapiリクエストが行われるようになりました。componentDidMountで非同期呼び出しによって作成されたコンポーネントをテストするにはどうすればよいですか?
このAPIは、配列data
の状態を設定します。レンダー機能では、data.map
関数を呼び出して、この配列から複数のコンポーネントをレンダリングします。必要な数のコンポーネントがレンダリングされたかどうかをテストするにはどうすればよいですか?
マイコンポーネント:
//CardGrid.js
import React from 'react';
import { Card, Col, Row } from 'antd';
import 'antd/dist/antd.css';
import { parseJSON } from './commonfunction';
import './CardGrid.css';
export default class extends React.Component {
constructor()
{
super();
this.state = {
data: {},
};
}
fetchData = async() => {
try
{
const data = await parseJSON(await fetch('http://localhost:3001/api/cards'));
console.log('data');
console.log(data);
this.setState({ data });
}
catch (e)
{
console.log('error is: ');
console.log(e);
}
}
componentDidMount() {
this.fetchData();
}
render() {
return (
<div style={{ background: '#ECECEC', padding: '30px' }}>
<Row gutter={16}>
{Object.keys(this.state.data).map((title) => {
return (<Col span="6" key={title}>
<Card title={title} bodyStyle={{
'fontSize': '6em',
}}>{this.state.data[title]}</Card>
</Col>);
})}
</Row>
</div>
);
}
};
今、私は私のAPIで指定されたレンダリングされているなど、多くのCard
コンポーネントがあるかどうかを確認します。
最初にfetch
関数を嘲って1要素を返すことでこれを試みました。次に、酵素のFull DOMレンダリングと上記の成分のmount
を使用して、それに1つの要素が含まれると考えます。
テストケース:
// It fails
import React from 'react';
import { Card } from 'antd';
import { mount } from 'enzyme';
import CardGrid from './CardGrid';
it('renders 1 Card element',() => {
fetch = jest.fn().mockImplementation(() =>
Promise.resolve(mockResponse(200, null, '{"id":"1234"}')));
const wrapper = mount(<CardGrid />);
expect(fetch).toBeCalled();
expect(wrapper.find(CardGrid).length).toEqual(1);
expect(wrapper.find(Card).length).toEqual(1);
});
すべてのテストは、それがカードの要素を見つけることができないことを除いて渡しています。 fetch mock関数も呼び出されます。私はカードコンポーネントを見つける前にsetTimeout関数を置くまで失敗します。
//It succeeds
import React from 'react';
import { Card } from 'antd';
import { mount } from 'enzyme';
import sinon from 'sinon';
import CardGrid from './CardGrid';
it('renders 1 Card elements', async() => {
fetch = jest.fn().mockImplementation(() =>
Promise.resolve(mockResponse(200, null, '{"id":"1234"}')));
const wrapper = mount(<CardGrid />);
expect(fetch).toBeCalled();
expect(wrapper.find(CardGrid).length).toEqual(1);
await setTimeoutP();
expect(wrapper.find(Card).length).toEqual(1);
});
function setTimeoutP() {
return new Promise(function (resolve, reject) {
setTimeout(() => {
console.log('111111111');
resolve();
}, 2000);
});
}
私には理解できない概念はありますか?このような非同期ロードコンポーネントをテストするにはどうすればよいですか?簡単にテスト可能にするにはどうすればよいでしょうか?どんな助けでも大歓迎です。ありがとう
本当に 'await parseJSON'が必要ですか?そのソースは含まれていませんが、非同期ではないと思います。 MDNの文書は、「価値が約束でなければ、価値を約束したものに変換し、それを待つ」と述べている。だから、それはうまくいくはずだが、このアプローチとテストフレームワークの何かがあるだろうか? – pherris
申し訳ありませんがparseJSONのソースは含まれていません。基本的には、fetch API呼び出しによって返されたResponseオブジェクトに対して '.json()'を呼び出します。私はそれが約束を返すので、それを待つ必要があります。 https://developer.mozilla.org/en-US/docs/Web/API/Body/json – Ayush
その場合、解決策は両方のことを約束することです( 'fetch'と' parseJSON'のために) )。 – pherris