我正在尝试在我的 Mocha 测试中使用 chai-as-promised 来测试一些打字稿代码。我不太能理解语法。所以我设置了一个最小的再现器:
// Sample promise that resolves on red, fails on other values
export const getRedColor = async (color: string): Promise<string> =>
new Promise((resolve, reject) => {
setTimeout(() => {
if (color === 'red') {
resolve(color);
} else {
reject(new Error(`You picked ${color}, should be red`));
}
}, 1000);
});
首先我使用 async/await 编写一个测试作为控制,前 2 个通过,后两个设计为失败。
import * as chai from 'chai';
import { expect } from 'chai';
import 'mocha';
import chaiAsPromised from 'chai-as-promised';
import { getRedColor, isRedColor } from '../src/index';
import { describe } from 'mocha';
describe('Testing failing promises with async/await', () => {
it('should pass on red', async () => {
let result = await getRedColor('red');
expect(result).to.equal('red');
});
it('should throw on blue', async () => {
try {
let result = await getRedColor('blue');
expect.fail('SHould not succeed');
} catch (e: any) {
expect(e.message).to.equal('You picked blue, should be red');
}
});
// Deliberately failing
it('should fail on blue', async () => {
let result = await getRedColor('blue');
expect(result).to.equal('blue');
});
// Deliberately failing
it('should throw on red', async () => {
try {
let result = await getRedColor('red');
expect.fail('Should not succeed');
} catch (e: any) {
expect(e.message).to.equal('You picked red, should be red');
}
});
});
然后(在同一个文件中)使用 chai 语法相同(2 次通过/2 次失败)
describe('Testing failing promises chai-as-promised', () => {
it('should pass on red', () => {
let result = getRedColor('red');
expect(result).to.eventually.equal('red');
});
it('should throw on blue', () => {
let result = getRedColor('blue');
expect(result).to.eventually.rejectedWith('You picked blue, should be red');
});
// Deliberately failing
it('should fail expecting rejection on red', () => {
let result = getRedColor('red');
expect(result).to.eventually.rejected;
});
// Deliberately failing
it('should fail resulting in blue', () => {
let result = getRedColor('blue');
expect(result).to.eventually.eql('blue');
});
});
所有测试都通过了——所以我一定做错了什么。我还检查了文档,建议将测试更改为
// Deliberately failing
it('should fail resulting in blue', () => {
let result = getRedColor('blue');
return result.to.eventually.eql('blue');
});
但这会导致错误
类型错误:无法读取未定义的属性(读取“最终”)
我想念什么?
我很接近。缺少返回语句或通知调用。这些是
return
和 notify()
风格的工作代码:
describe('Testing failing promises chai-as-promised', () => {
it('should pass on red', () => {
let result = getRedColor('red');
return expect(result).to.eventually.equal('red');
});
it('should throw on blue', () => {
let result = getRedColor('blue');
return expect(result).to.eventually.rejectedWith('You picked blue, should be red');
});
describe('Testing failing promises chai-as-promised', () => {
it('should pass on red', (done) => {
let result = getRedColor('red');
expect(result).to.eventually.equal('red').notify(done);
});
it('should throw on blue', (done) => {
let result = getRedColor('blue');
expect(result).to.eventually.rejectedWith('You picked blue, should be red').notify(done);
});
});
希望能帮助那些在相同细节上苦苦挣扎的人
正如你所说,你已经很接近了。我最近遇到了“每个异步/Promise 测试在应该失败时都通过了”问题。有几个部分组合在一起可以解决这个问题。
虽然
done
完成功能有效,但它限制您每次测试只能进行一次异步调用。我也觉得读起来有点麻烦。
我采用的方法是
async
方法和 await
调用。最后一部分对我来说并不明显,所以我想我应该向遇到此问题的其他人解释一下......这是您最初应该失败但没有失败的案例之一:
expect
这是您发布的答案,它有效,但使用
// original
it('should fail expecting rejection on red', () => {
let result = getRedColor('red');
expect(result).to.eventually.rejected;
});
完成功能:
done
我建议的答案是使用
// first cut
it('should pass on red', (done) => {
let result = getRedColor('red');
expect(result).to.eventually.equal('red').notify(done);
});
和
async
:await
同样,测试失败的承诺:
// Use async and await
it('should pass on red', async () => {
await expect(getRedColor('red')).eventually.equals('red')
})
首先使用
// Original
it('should fail expecting rejection on red', () => {
let result = getRedColor('red');
expect(result).to.eventually.rejected;
});
进行剪切(我个人不喜欢,但确实有效):
done
决赛:
// first cut from earlier answer
it('should throw on blue', (done) => {
let result = getRedColor('blue');
expect(result).to.eventually.rejectedWith('You picked blue, should be red').notify(done);
});
这可以让您将任意数量的 Promise 测试放在一起:
// use async and await
it('should throw on blue', async () => {
await expect(getRedColor('blue')).eventually.rejectedWith('You picked blue, should be red')
})