I promise that you will get to read interesting stuff 😝🙄
This article talks about false positive tests in Jest with Promises
When you write assertion inside resolution of a Promise i.e. then or catch block, then it becomes mandatory to follow either of below three,
1. The test should return the Promise who’s resolution behaviour is under test
Assume `getData()`when resolved will return ‘Hi’
it(‘should say hi on getting data’, () => {
return getData().then((data) => {
expect(data).toEqual(“Hi”);
});
});
If you don’t return the Promise from getData(), then the test becomes false positive, and below invalid test will keep passing,
it(‘should say hi on getting data’, () => {
getData().then((data) => {
expect(data).toEqual(“Foo..”);
});
});
2. The test should use async await
it(‘should say hi on getting data’, async () => {
await getData().then((data) => {
expect(data).toEqual(“Hi”);
});
});
If you now change the expectation from ‘Hi’ to ‘Foo..’ then this test will fail.
3. The test should use jasmines done callback
it(‘should say hi on getting data’, (done) => {
getData().then((data) => {
expect(data).toEqual(“Hi”);
});
done();
});
If you now change the expectation from ‘Hi’ to ‘Foo..’ then this test will fail.
There is no issue for #2 and #3 above. But most of the developers follow #1 and which comes with possibility of test becoming false positive..
How to solve that ?
A Lint rule -thats it!
Create a lint rule which verifies that, a test returns Promise, if there are assertion statements inside Promise resolution block.
I was fortunate enough to do a contribution for this in eslint-plugin-jest. This lint rule is now released.
Interestingly this rule caught one false positive test in Jest itself. It also caught many false positive tests in some of the project that I work on. If you also work on a project which uses Jest and Promises, then run this rule, you may also catch some false positive tests.