如何在Jest中跟踪失败的异步测试? [英] How to trace a failed asynchronous test in Jest?
问题描述
-更新-
已确定问题.
在实际的代码库中,将断言传递给导入的回调,一旦回调以失败的测试执行,就会引发承诺拒绝.
In the actual codebase the assertion is passed to a imported callback, and once the callback executes with a failed test, it raises a promise rejection.
因此,这与测试的实际编写方式很接近:
So, this is close to how the test was actually written:
describe( "file system", () => {
it( "should check if the file exists", async () => {
call( async () => {
const received = await fileExists();
const expected = true;
expect( received ).toBe( expected );
});
});
});
并以更简单的方式显示复杂的回调以产生相同的问题:
and the complex callback is presented in a simpler way to produce the same issue:
export function call( callback) {
callback();
}
-更新-
以下代码有效.
我从大型代码库中提取了一小部分代码,以提高可视性.如果我只运行下面的代码,它将按预期工作.我认为实际的代码库中存在问题.
I picked up a small portion of the code from a large codebase for better visibility. If I run just the following piece of code, it works as expected. I think there's an issue in the actual codebase.
@Flask关于处理未处理的诺言拒绝的建议为该问题增加了很大的价值.
@Flask's recommendation of handling the unhandled promise rejections centrally added a great value to the question.
请考虑以下测试:
import fileExists, { call } from "./exists";
describe( "file system", () => {
it( "should check if the file exists", async () => {
const received = await fileExists();
const expected = true;
expect( received ).toBe( expected );
});
});
适用于以下来源:
import fs, { constants } from "fs";
import { promisify } from "util";
export default async function fileExists() {
const path = ".nonexistent";
const access = promisify( fs.access );
try {
await access( path, constants.F_OK );
} catch {
return false;
}
return true;
}
当fileExists
拒绝返回false
时,将收到预期的.但这无助于追踪失败测试的根源.UnhandledPromiseRejectionWarning
When fileExists
rejects returns false
, an UnhandledPromiseRejectionWarning
is received as expected. But this does not help trace the source of the failed test.
对于同步测试,Jest显示测试路径(即file system › should check if the file exists
),这有助于跟踪失败测试的来源.
For synchronous tests, Jest shows the path to the test (i.e. file system › should check if the file exists
) which helps trace the source of the failed test.
实现异步测试的最佳方法是什么?
What is the best way to achieve this for asynchronous tests?
推荐答案
UnhandledPromiseRejectionWarning
在这里不是必需的.它不等于失败的测试,因为它不会在断言通过时阻止测试通过.这意味着代码编写方式错误,并且包含未链接的承诺.
UnhandledPromiseRejectionWarning
is not expected here. It's not equivalent to failed test because it doesn't prevent a test to pass if assertions pass. It means that the code was written the wrong way and contains unchained promises.
只有在测试中省略了await
时,它才会发生:
It can happen only if await
was omitted in the test:
fileExists(); // no await
或fileExists
函数包含未处理的宽松承诺:
Or fileExists
function contains loose unhandled promises:
fileExists() {
whatever() // no return
.then(() => {
whatever() // no return
}) // no catch to suppress errors
}
在setupFiles
中拥有一个好习惯:
process.on('unhandledRejection', console.error);
与UnhandledPromiseRejectionWarning
相比,它提供了更多有用的输出,并允许基于错误堆栈来调试问题.
It provides more useful output than UnhandledPromiseRejectionWarning
and allows to debug the problem based on error stack.
这篇关于如何在Jest中跟踪失败的异步测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!