我正在努力找出在使用async/await时在Mocha测试中验证承诺被拒绝的最佳方法.
这是一个有效的例子,但我不喜欢should.be.rejectedWith
返回一个需要从测试函数返回的promise才能正确评估.使用async/await删除了测试值的这个要求(正如我对wins()
下面的结果所做的那样),我觉得很可能在某些时候会忘记return语句,在这种情况下测试将始终通过.
// Always succeeds
function wins() {
return new Promise(function(resolve, reject) {
resolve('Winner');
});
}
// Always fails with an error
function fails() {
return new Promise(function(resolve, reject) {
reject('Contrived Error');
});
}
it('throws an error', async () => {
let r = await wins();
r.should.equal('Winner');
return fails().should.be.rejectedWith('Contrived Error');
});
Run Code Online (Sandbox Code Playgroud)
感觉应该可以使用async/await将拒绝转换为异常的事实并将其与Chai的should.throw相结合,但我无法确定正确的语法.
理想情况下这可行,但似乎不是:
it('throws an error', async () => {
let r = await wins();
r.should.equal('Winner');
(await fails()).should.throw(Error);
});
Run Code Online (Sandbox Code Playgroud) 我正在尝试编写测试来测试连接到mongo的方法,但我实际上并不想让mongo运行并实际建立连接以使我的测试成功通过.
这是我当前的测试,当我的mongo守护程序运行时,它是成功的.
describe('with a valid mongo string parameter', function() {
it('should return a rejected promise', function(done) {
var con = mongoFactory.getConnection('mongodb://localhost:27017');
expect(con).to.be.fulfilled;
done();
});
});
Run Code Online (Sandbox Code Playgroud)
mongoFactory.getConnection代码:
getConnection: function getConnection(connectionString) {
// do stuff here
// Initialize connection once
MongoClient.connect(connectionString, function(err, database) {
if (err) {
def.reject(err);
}
def.resolve(database);
});
return def.promise;
}
Run Code Online (Sandbox Code Playgroud) 我有一个拒绝承诺的课程:
Sync.prototype.doCall = function(verb, method, data) {
var self = this;
self.client = P.promisifyAll(new Client());
var res = this.queue.then(function() {
return self.client.callAsync(verb, method, data)
.then(function(res) {
return;
})
.catch(function(err) {
// This is what gets called in my test
return P.reject('Boo');
});
});
this.queue = res.delay(this.options.throttle * 1000);
return res;
};
Sync.prototype.sendNote = function(data) {
var self = this;
return self.doCall('POST', '/Invoice', {
Invoice: data
}).then(function(res) {
return data;
});
};
Run Code Online (Sandbox Code Playgroud)
在我的测试中:
return expect(s.sendNote(data)).to.eventually.be.rejectedWith('Boo');
Run Code Online (Sandbox Code Playgroud)
但是,当测试通过时,它会将错误抛出到控制台.
未处理的拒绝错误:嘘......
对于非promise错误,我使用bind来测试以防止在Chai可以包装和测试之前抛出错误:
return expect(s.sendNote.bind(s, data)).to.eventually.be.rejectedWith('Boo'); …
Run Code Online (Sandbox Code Playgroud) 我正在使用Mocha来测试返回promise的异步函数.
测试承诺是否解析为正确值的最佳方法是什么?
我正在使用chai-as-promised + mocha来编写一些selenium-webdriver测试.由于webdriver广泛使用promises,我想如果我使用chai-as-promised进行那些类型的测试会更好.
问题是当测试失败时,mocha没有正确捕获错误,它只是失败而没有输出任何东西.
示例代码:
it 'tests log', (next) ->
log = @client.findElement(By.css("..."))
Q.all([
expect(log.getText()).to.eventually.equal("My Text")
expect(log.findElement(By.css(".image")).getAttribute('src'))
.to.eventually.equal("/test.png")
]).should.notify(next)
Run Code Online (Sandbox Code Playgroud)
根据记录的行为,当预期失败时,chai-as-promise应该将错误传递给mocha.对?
作为变种,
我也试过这些,但无济于事:
# same, no error on failure
it 'tests log', (next) ->
log = @client.findElement(By.css("..."))
Q.all([
expect(log.getText()).to.eventually.equal("My Text")
expect(log.findElement(By.css(".image")).getAttribute('src'))
.to.eventually.equal("/test.png")
]).should.notify(next)
Run Code Online (Sandbox Code Playgroud)
# same, no error shown on failure
it 'tests log', (next) ->
log = @client.findElement(By.css("..."))
expect(log.getText()).to.eventually.equal("My Text")
.then ->
expect(log.findElement(By.css(".image")).getAttribute('src'))
.to.eventually.equal("/test.png").should.notify(next)
Run Code Online (Sandbox Code Playgroud)
## DOES NOT EVEN …
Run Code Online (Sandbox Code Playgroud) 我正在尝试将chai-as-promised
包与 TypeScript一起使用。首先,以下代码在简单的 JavaScript 中运行良好。
import * as chai from 'chai';
import * as chaiAsPromised from 'chai-as-promised';
chai.use(chaiAsPromised);
const expect = chai.expect;
import * as sinon from 'sinon';
import { MyClass } from '.';
describe('Test my class', () => {
let myClass: MyClass;
beforeEach(() => {
myClass = new MyClass();
});
it('Should render home', () => {
const req = new RequestMock();
const res = new ResponseMock();
return expect(myClass.getHomePage(req, res)).to.be.fulfilled()
.then((returnedValue) => {
chai.expect(returnedValue).to.not.be.equal([]);
});
});
});
Run Code Online (Sandbox Code Playgroud)
这段代码出现以下错误:
...它指出了这一点: …
我正试图通过业力单元测试chai-as-promised
来处理$q
承诺.
svc.test = function(foo){
if (!foo){
// return Promise.reject(new Error('foo is required'));
return $q.reject(new Error('foo is required'));
} else {
// get data via ajax here
return $q.resolve({});
}
};
it.only('should error on no foo', function(){
var resolvedValue = MyServices.test();
$rootScope.$apply();
return resolvedValue.should.eventually.be.rejectedWith(TypeError, 'foo is required');
});
Run Code Online (Sandbox Code Playgroud)
单元测试只是超时了.我不确定我在这里做错了什么来得到正确解决的承诺.这似乎是一个使用问题$q
- 当我使用原生Promise.reject()
它工作正常.
我在这里提交了一张票,但似乎没有人回应:https: //github.com/domenic/chai-as-promised/issues/150
我正在使用chai-as- promise来测试一些承诺.我的问题是我不确定如何在一次测试中使用多个期望语句.为了expect().to.be.fulfilled
使其正常工作,我需要将其返回,如下所示:
it('test', () => {
return expect(promise).to.be.fulfilled
}
Run Code Online (Sandbox Code Playgroud)
......或者notify
像这样使用:
it('test', (done) => {
expect(promise).to.be.fulfilled.notify(done)
}
Run Code Online (Sandbox Code Playgroud)
问题来自于我需要检查的另一件事,例如调用某个函数,如下所示:
it('test', (done) => {
var promise = doSomething()
expect(sinon_function_spy.callCount).to.equal(1)
expect(promise).to.be.fulfilled.notify(done)
})
Run Code Online (Sandbox Code Playgroud)
这里的问题是,因为doSomething()
是异步的,所以sinon_function_spy
当我调用它时,调用可能还没有发生expect
,使得这个测试变得不稳定.如果我使用a then
,像这样:
it('test', (done) => {
var promise = doSomething()
promise.then(() => {
expect(sinon_function_spy.callCount).to.equal(1)
})
expect(promise).to.be.fulfilled.notify(done)
})
Run Code Online (Sandbox Code Playgroud)
然后测试在技术上传递并按预期失败,但它将失败,因为由于then
调用中抛出的异常,promise被拒绝.同样,如果我有一个承诺预计拒绝的情况:
it('test', (done) => {
var promise = doSomething()
promise.then(() => {
expect(sinon_function_spy.callCount).to.equal(1)
})
expect(promise).to.be.rejected.notify(done)
})
Run Code Online (Sandbox Code Playgroud)
然后检查sinon_function_spy
永远不会被调用,因为承诺被拒绝并且没有调用 …
使用Mocha和chai-as-promised,我试图测试我的承诺是否得到正确解决和拒绝。但是expect
由 chai-as-promised 提供的功能并没有正确地导致测试失败。例子:
测试.js
const chai = require('chai')
chai.use(require('chai-as-promised'))
const expect = chai.expect
describe('foo', () => {
it('resolve expected', () => {
expect(new Promise((res,rej) => {res()})).to.be.fulfilled
})
it('resolve unexpected', () => {
expect(new Promise((res,rej) => {res()})).to.be.rejected
})
it('reject expected', () => {
expect(new Promise((res,rej) => {rej()})).to.be.rejected
})
it('reject unexpected', () => {
expect(new Promise((res,rej) => {rej()})).to.be.fulfilled
})
})
Run Code Online (Sandbox Code Playgroud)
当我执行mocha test.js
:
foo
? resolve expected
? resolve unexpected
(node:2659) UnhandledPromiseRejectionWarning: Unhandled promise rejection …
Run Code Online (Sandbox Code Playgroud) 我有一个异步函数,它运行 2000 毫秒,然后它会抛出异常。我正在尝试使用 Mocha/chai 完全测试这种行为,但显然我做错了。
这就是我尝试过的:
第一的:
expect(publisher.dispatchMessage<ExampleResponseMessage>(message, {}, 2 * 1000)).to.eventually.throw();
Run Code Online (Sandbox Code Playgroud)
这将测试标记为通过(运行时间为 52 毫秒),但在 2 秒后抛出异常。所以显然它根本没有等待该功能的承诺。
第二:
expect(async () => {
await publisher.dispatchMessage<ExampleResponseMessage>(message, {}, 2 * 1000);
}).to.throw();
Run Code Online (Sandbox Code Playgroud)
测试失败:应在预定义超时后拒绝预定消息:AssertionError:预期 [Function] 在 Context.mocha_1.it (test\integration\rpc-communication.spec.ts:75:16) 处引发错误
预期行为是测试通过,因为在 2000 毫秒后抛出异常,这在给定的测试用例超时 4000 毫秒内。
附加信息:
这会奏效。承诺因错误而被拒绝(我也可以将其更改为用字符串拒绝)。这应该证明 dispatchMessage() 按预期工作。测试用例需要 2002 毫秒,然后通过。
try {
await publisher.dispatchMessage<ExampleResponseMessage>(message, {}, 2 * 1000);
} catch (err) {
expect(err).to.be.an('Error');
}
Run Code Online (Sandbox Code Playgroud)
题:
如何正确测试异步函数是否引发异常?
chai-as-promised ×10
chai ×9
mocha.js ×8
javascript ×5
node.js ×4
typescript ×2
angularjs ×1
async-await ×1
bluebird ×1
es6-promise ×1
karma-runner ×1
mongodb ×1
promise ×1
selenium ×1
testing ×1
unit-testing ×1