我正在使用Browser Runner在Mocha中运行一些异步测试,并尝试使用Chai的expect风格断言:
window.expect = chai.expect;
describe('my test', function() {
it('should do something', function (done) {
setTimeout(function () {
expect(true).to.equal(false);
}, 100);
}
}
这并没有给出正常的失败断言消息,相反,我得到:
Error: the string "Uncaught AssertionError: expected true to equal false" was thrown, throw an Error :)
at Runner.fail (http://localhost:8000/tests/integration/mocha/vendor/mocha.js:3475:11)
at Runner.uncaught (http://localhost:8000/tests/integration/mocha/vendor/mocha.js:3748:8)
at uncaught (http://localhost:8000/tests/integration/mocha/vendor/mocha.js:3778:10)
所以很明显它捕捉到了错误,只是没有正确地显示出来。你知道该怎么做吗?我想我可以用一个错误对象来调用"done“,但这样我就失去了像Chai这样的东西的优雅,它变得非常笨拙……
发布于 2013-03-05 02:07:24
异步测试在失败的expect()
操作上生成一个异常,it()
无法捕获该异常,因为该异常被抛出在it()
的作用域之外。
显示的捕获异常是使用node下的process.on('uncaughtException')
或浏览器中的window.onerror()
捕获的。
要解决此问题,您需要在setTimeout()
调用的异步函数中捕获异常,以便以异常作为第一个参数调用done()
。您还需要调用不带参数的done()
来表示成功,否则mocha将报告一个超时错误,因为您的测试函数永远不会发出已完成的信号:
window.expect = chai.expect;
describe( 'my test', function() {
it( 'should do something', function ( done ) {
// done() is provided by it() to indicate asynchronous completion
// call done() with no parameter to indicate that it() is done() and successful
// or with an error to indicate that it() failed
setTimeout( function () {
// Called from the event loop, not it()
// So only the event loop could capture uncaught exceptions from here
try {
expect( true ).to.equal( false );
done(); // success: call done with no parameter to indicate that it() is done()
} catch( e ) {
done( e ); // failure: call done with an error Object to indicate that it() failed
}
}, 100 );
// returns immediately after setting timeout
// so it() can no longer catch exception happening asynchronously
}
}
在所有测试用例上这样做既烦人又不干练,因此您可能希望提供一个函数来为您完成此操作。让我们将此函数称为check()
function check( done, f ) {
try {
f();
done();
} catch( e ) {
done( e );
}
}
使用check()
,您现在可以重写异步测试,如下所示:
window.expect = chai.expect;
describe( 'my test', function() {
it( 'should do something', function( done ) {
setTimeout( function () {
check( done, function() {
expect( true ).to.equal( false );
} );
}, 100 );
}
}
发布于 2015-12-19 11:33:53
以下是我对ES6/ES2015 promises和ES7/ES2016 async/await的通过测试。希望这篇文章能为任何研究这个话题的人提供一个很好的更新答案:
import { expect } from 'chai'
describe('Mocha', () => {
it('works synchronously', () => {
expect(true).to.equal(true)
})
it('works ansyncronously', done => {
setTimeout(() => {
expect(true).to.equal(true)
done()
}, 4)
})
it('throws errors synchronously', () => {
return true
throw new Error('it works')
})
it('throws errors ansyncronously', done => {
setTimeout(() => {
return done()
done(new Error('it works'))
}, 4)
})
it('uses promises', () => {
var testPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Hello')
}, 4)
})
testPromise.then(result => {
expect(result).to.equal('Hello')
}, reason => {
throw new Error(reason)
})
})
it('uses es7 async/await', async (done) => {
const testPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Hello')
}, 4)
})
try {
const result = await testPromise
expect(result).to.equal('Hello')
done()
} catch(err) {
done(err)
}
})
/*
* Higher-order function for use with async/await (last test)
*/
const mochaAsync = fn => {
return async (done) => {
try {
await fn()
done()
} catch (err) {
done(err)
}
}
}
it('uses a higher order function wrap around async', mochaAsync(async () => {
const testPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Hello')
}, 4)
})
expect(await testPromise).to.equal('Hello')
}))
})
发布于 2014-02-10 23:22:35
如果你喜欢promised,试试Chai as Promised + Q,它允许这样的东西:
doSomethingAsync().should.eventually.equal("foo").notify(done);
https://stackoverflow.com/questions/11235815
复制相似问题