Posted at

Async Functionで_.deferだらけの非同期テストを若干マシにする

More than 1 year has passed since last update.

非同期関数の中身が実行された後の結果を検証したい時は、下記のように _.defer を使って書いていました。コールバックに次の処理を書いていくのでインデントが増えるし、doneを呼ばないといけない(そして、よく忘れる)のが、面倒くさい。

it('should be ok', (done) => {

assert.equal(wrapper.find('.upload-button').text(), 'アップロード');

wrapper.find('.upload-button').simulate('click');

assert.equal(wrapper.find('.upload-button').text(), '画像をリサイズ中');

// 非同期に行われる画像のリサイズが完了するのを待つ
_.defer(() => {
assert.equal(wrapper.find('.upload-button').text(), 'アップロード中');

server.respond();

// レスポンスを処理するコールバックの完了を待つ
_.defer(() => {
assert.equal(wrapper.find('.upload-button').text(), 'アップロード');

done();
});
});
});

ECMAScript 2017に入る1Async Functionを使うと、下記のように書き直せます。インデントとdoneがいらなくなりました。

const defer = () => new Promise((resolve) => setTimeout(resolve, 0));

it('should be ok', async () => {
assert.equal(wrapper.find('.upload-button').text(), 'アップロード');

wrapper.find('.upload-button').simulate('click');

assert.equal(wrapper.find('.upload-button').text(), '画像をリサイズ中');

// 非同期に行われる画像のリサイズが完了するのを待つ
await defer();

assert.equal(wrapper.find('.upload-button').text(), 'アップロード中');

server.respond();

// レスポンスを処理するコールバックの完了を待つ
await defer();

assert.equal(wrapper.find('.upload-button').text(), 'アップロード');
});

各種バージョンは下記の通りです。たぶんmochaでも動くはず。

- node 6.9.4

- react 15.4.2

- jest 18.1.0

- enzyme 2.7.1

- babel-preset-es2017 6.22.0





  1. ECMAScript 2017: the final feature set http://www.2ality.com/2016/02/ecmascript-2017.html