Jest’s ‘beforeEach’ may not be running the way you think it does…

For the last few years I’ve been a pretty heavy user of Jest, I use it as my test runner across both my FE and BE stacks. While I’m a daily driver of the framework I was recently very surprised to discover a situation where one of my assumptions of how it runs, particularly the order of its beforeEach method was totally incorrect.

Let’s start with an ordinary jest test describe:

Fairly standard. The beforeAll will run first, followed by a beforeEach prior to each test running, resulting with the output of:

No surprises there.

Now what if we added a level of nesting within that test. Say there was another describe block with its own series of tests that all require the same beforeEach setup and a common beforeAll setup. Jest supports this behaviour, although it is something that I don’t use often:

Now what I assumed would run here would be the same behaviour as before:

The top-beforeAll running first, the top-beforeEach running before each test and then once before the describe block.

Then the nested-beforeAll and the nested-beforeEach before each test within the describe block. That assumption was wrong.

What I had incorrectly assumed was the beforeEach call would apply to the describe block in the same way it does with a test block: run once before the inner content of the block, regardless of it being a test or a describe. The actual situation totally different:

It will run before each test even if they are nested. So while I was expecting the top-beforeEach to have run 3 times total, once for each method within its block, it actually runs 4 times!

The other behaviour here to consider is that the nested-beforeAll actually runs before the top-beforeEach, meaning that if your nested-beforeAll was relying on the top-beforeEach to have run before the block was entered, you’re going to be out of luck.

This behaviour compounds with yet another level of nesting:

I don’t think the way the beforeEach handles test vs describe blocks differently is immediately obvious and something worth knowing about. I should also mention that afterEach also runs this way, although the order is inverted.

Do you have some beforeEach blocks running more often than you realised?



Holistic software engineer.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store