#前提
- Vue.js 2.1.1
- karma + mocha + chai
#経緯
- Vm のデータを更新後、画面上の表示文字列が変わることを確認する Unittest を書いた
- 当初 browser に PhantomJS を指定していたが、Chrom に変更した
- assert がうまく出ない!!
#原因
- Vue.nextTick() が ブラウザの Promise サポート有無によってい使い方が変わる
- ブラウザが Promiseをサポートしない nextTick() のコールバックを指定する (PhantomJS)
it('画面が更新される', function(done) {
cmp.upate_value = 'test';
Vue.nextTick(function() {
expect(cmp.$el.textContent).to.equal('test');
done();
});
});
- プラウザが Promiseをサポート する nextTick() は コールバックをサポートせず、Promise を返す (Chrome など)
it('画面が更新される', function(done) {
cmp.upate_value = 'test';
Vue.nextTick()
.then(function() {
expect(cmp.$el.textContent).to.equal('test');
})
.then(done)
.catch(done);
});
解決案
- Waitしてくれる関数を定義する
/**
* 更新待ち
* @param {function} callback
* @param {function} done
*/
function waitForUpdate(callback, done) {
/** Promise がサポートされている場合、Promise が返される **/
if(typeof Promise !== 'undefined' && isNative(Promise)) {
Vue.nextTick().then(callback).then(done).catch(done);
}
/** Promise がサポートされていない場合、Callbackを指定する **/
else {
Vue.nextTick(function () {
callback();
done();
});
}
}
function isNative(Ctor) {
return /native code/.test(Ctor.toString());
}
テストはこんな感じ
it('画面が更新される', function(done) {
cmp.upate_value = 'test';
waitForUpdate(function() {
expect(cmp.$el.textContent).to.equal('test');
},done);
});