如何在 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
rejects 返回 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 会显示测试的路径(即文件系统 › 应该检查文件是否存在
),这有助于追踪失败测试的来源.
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
中有一个很好的做法:
It's a good practice to have in 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屋!