Mocha await/async 处理(预期)错误
Mocha await/async handling (expected) errors
前段时间我很好奇如何使用 Mocha 执行异步测试以及那些预期结果会出错的测试(参见 )
现在我使用 await/async 对较新版本的 nodejs 进行了相同的尝试。只是一个简单的案例,但由于我需要将代码包装在 try / catch
块中,所以事情变得一发不可收拾。
经过长时间的测试,我最终找到了解决方案,但它看起来不太好。
所以我正在寻找更好的方法。
测试看起来像这样:
it('myTest', async function () {
// THIS WORKS => CODE OPTION 1:
// this works, it uses promises but not await/async
return somePromiseFunction()
.then(() => Promise.reject(new Error('Expected method to reject.')))
.catch(err => assert.ok(err instanceof Error, 'This should be an error!'));
// THIS WORKS => CODE OPTION 2:
// this works, it uses await/async
let forceFail = false;
try {
await somePromiseFunction();
forceFail = true;
} catch (err) {}
if (forceFail) assert.ok(false, 'Expected method to reject.');
// WONT WORK => CODE OPTION 3:
try {
await somePromiseFunction();
assert.ok(false, 'you shouln\'t be here');
} catch (err) {
assert.ok(err instanceof Error, 'This should be an error!');
}
});
选项 1 和 2 都有效。选项 1 使用经典的 Promise.then.catch
语法,没关系。选项 2 是我使事情正常进行的唯一方法,但理解/维护起来非常复杂。它依赖于一种全局变量和处理状态,而且看起来不太好。
代码中有一个选项3,但是不起作用。类似这样的东西很容易阅读,但它根本不起作用,第一个断言和第二个断言都不行。
如果您删除 try / catch
块,那么它也不会起作用。
谢谢。
在第三个选项中,err
将始终是 undefined
,因为您将异常捕获为 e
,而不是 err
。而且断言总是会失败,因为 undefined
不是 Error
.
的实例
我找到了一种方法,但你需要升级到节点版本 10。我使用的是 8,但 assert 中包含的这个新功能以优雅的方式解决了我的问题。
而不是尝试这个:
// WONT WORK => CODE OPTION 3:
try {
await somePromiseFunction();
assert.ok(false, 'you shouln\'t be here');
} catch (err) {
assert.ok(err instanceof Error, 'This should be an error!');
}
这样做:
// this works!
await assert.rejects(
async () => somePromiseFunction(),
Error
);
您还可以验证抛出的错误类型,但在我的情况下 Error
就足够了。
编辑:async () =>
并不是真正必要的,我最后得到了一行断言(第二个参数是可选的,但我宁愿保留它):
await assert.rejects(somePromiseFunction(), Error);
前段时间我很好奇如何使用 Mocha 执行异步测试以及那些预期结果会出错的测试(参见
现在我使用 await/async 对较新版本的 nodejs 进行了相同的尝试。只是一个简单的案例,但由于我需要将代码包装在 try / catch
块中,所以事情变得一发不可收拾。
经过长时间的测试,我最终找到了解决方案,但它看起来不太好。
所以我正在寻找更好的方法。
测试看起来像这样:
it('myTest', async function () {
// THIS WORKS => CODE OPTION 1:
// this works, it uses promises but not await/async
return somePromiseFunction()
.then(() => Promise.reject(new Error('Expected method to reject.')))
.catch(err => assert.ok(err instanceof Error, 'This should be an error!'));
// THIS WORKS => CODE OPTION 2:
// this works, it uses await/async
let forceFail = false;
try {
await somePromiseFunction();
forceFail = true;
} catch (err) {}
if (forceFail) assert.ok(false, 'Expected method to reject.');
// WONT WORK => CODE OPTION 3:
try {
await somePromiseFunction();
assert.ok(false, 'you shouln\'t be here');
} catch (err) {
assert.ok(err instanceof Error, 'This should be an error!');
}
});
选项 1 和 2 都有效。选项 1 使用经典的 Promise.then.catch
语法,没关系。选项 2 是我使事情正常进行的唯一方法,但理解/维护起来非常复杂。它依赖于一种全局变量和处理状态,而且看起来不太好。
代码中有一个选项3,但是不起作用。类似这样的东西很容易阅读,但它根本不起作用,第一个断言和第二个断言都不行。
如果您删除 try / catch
块,那么它也不会起作用。
谢谢。
在第三个选项中,err
将始终是 undefined
,因为您将异常捕获为 e
,而不是 err
。而且断言总是会失败,因为 undefined
不是 Error
.
我找到了一种方法,但你需要升级到节点版本 10。我使用的是 8,但 assert 中包含的这个新功能以优雅的方式解决了我的问题。
而不是尝试这个:
// WONT WORK => CODE OPTION 3:
try {
await somePromiseFunction();
assert.ok(false, 'you shouln\'t be here');
} catch (err) {
assert.ok(err instanceof Error, 'This should be an error!');
}
这样做:
// this works!
await assert.rejects(
async () => somePromiseFunction(),
Error
);
您还可以验证抛出的错误类型,但在我的情况下 Error
就足够了。
编辑:async () =>
并不是真正必要的,我最后得到了一行断言(第二个参数是可选的,但我宁愿保留它):
await assert.rejects(somePromiseFunction(), Error);