How to find the root cause of a failing test if Jest doesn’t tell you what’s wrong
Debugging tests can be hard — but it doesn’t need to be
Writing tests can feel slow and mundane. Testing frameworks like Jest are often making our lives as developers easier through a great developer experience. I’ve been using Jest in both frontend applications (e.g. with Angular) and in Node.js based services (e.g. Express.js) for quite a while.
Recently, one Angular project was updated and required developers to use Node 14 from now on (previously, the project required Node 10). The update went through smoothly and we didn’t encounter any issues in this process. However, I increasingly noticed an issue that I found rather strange. If an uncaught exception occurred in a test case Jest seemed to be stuck and not progress any further no matter how long I’d wait. The error message always looked like this and didn’t tell me much:
UnhandledPromiseRejectionWarning: TypeError: Converting circular structure to JSON
Initially, I didn’t think too much of it. By checking each test case one by one I usually found the root cause. After a few more times, I became curious where this new behaviour came from, though. A simple online search revealed that I wasn’t the only one affected. The issue seems to occur more likely in Angular projects when using Node 14.
How to get the actual error message in Jest with --detectOpenHandles
Luckily, someone pointed out a way around this while this issue is still present. Even though Jest aims to work out of the box by requiring as few configuration as possible Jest has a lot of configuration options in case you need it. In our case, there’s an option called --detectOpenHandles
that solves our problem. By using this command, Jest should print the actual exception which should be enough to locate the bug in the code.
jest --detectOpenHandles
Beware: while this command is useful to debug problems it also has a noticeable performance penalty as stated in the Jest documentation! Therefore, we should refrain from using --detectOpenHandles
if there are no issues. But in cases like this, this option is quite useful to uncover the root cause (e.g. NullInjectorError: No provider for HttpClient).
Pro tip: you can define an alias to invoke this command even without having a script in your package.json
or remembering the command when you need it. In your .zshrc
or .bash_profile
file you can define an alias (I’ve named it jest-troubleshoot in this case). Then, in your terminal you can use this alias by typing jest-troubleshoot
in any project that uses Jest as testing framework.
alias jest-troubleshoot='npx jest --detectOpenHandles'
Conclusion
Thanks for reading this short post about a simple trick to find the root cause in tests when Jest doesn’t log it. While the issue described in this post is somewhat annoying we have at least an easy way to get around this and find the root cause of a failing test. Do you know other debugging tricks when it comes to Jest? Let me know in the comments.