Tho*_*low 79 javascript unit-testing mocha.js
我正在使用浏览器运行器在Mocha中运行一些异步测试,我正在尝试使用Chai的期望样式断言:
window.expect = chai.expect;
describe('my test', function() {
it('should do something', function (done) {
setTimeout(function () {
expect(true).to.equal(false);
}, 100);
}
}
Run Code Online (Sandbox Code Playgroud)
这不会给我正常的失败断言消息,而是我得到:
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)
Run Code Online (Sandbox Code Playgroud)
所以它显然正在捕捉错误,它只是没有正确显示它.任何想法如何做到这一点?我想我可以用一个错误对象调用"完成",但后来我失去了像柴这样的东西的所有优雅,它变得非常笨重......
Jea*_*ent 94
您的异步测试会在失败的expect()操作上生成异常,it()因为异常被抛出了it()范围之外,因此无法捕获.
您看到的捕获的异常是使用process.on('uncaughtException')under node或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
}
}
Run Code Online (Sandbox Code Playgroud)
在所有测试用例上这样做很烦人,而不是干,所以你可能想要为你提供一个功能.我们叫这个函数check():
function check( done, f ) {
try {
f();
done();
} catch( e ) {
done( e );
}
}
Run Code Online (Sandbox Code Playgroud)
现在,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 );
}
}
Run Code Online (Sandbox Code Playgroud)
Ric*_*ter 19
以下是我对ES6/ES2015承诺和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')
}))
})
Run Code Online (Sandbox Code Playgroud)
xin*_*ink 13
如果你喜欢承诺,可以尝试Chai作为Promised + Q,它允许这样的东西:
doSomethingAsync().should.eventually.equal("foo").notify(done);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
43153 次 |
| 最近记录: |