BeforeAll vs. BeforeEach. When to use them?
Asked Answered
S

3

55

I was recently looking over a co-workers code and I realized that he implements a jest function in a BeforeAll function at the top of the describe call, and then creates a data object in a beforeEach function. This made me wonder, what exactly are the differences between BeforeAll and BeforeEach.

It was time... I went to Google!! I did find some articles that helped shed some light on some of the functionality differences between the two.

Findings 1: http://breazeal.com/blog/jasmineBefore.html

Findings 2: Difference between @Before, @BeforeClass, @BeforeEach and @BeforeAll

Given the articles I found that BeforeAll is called once and only once. While the BeforeEach is called before each individual test. Which was great! I now had a better idea of when it was being called!

I also found out that the BeforeAll is best used for initializing code. Which makes perfect sense! Initialize it once. Boom, you're done.

My confusion I am having is when is something initialized and when is it not? I have found that BeforeEach in our code is used more often than not. What I am curious about is what kind of code is considered to be "initializing" code, vs whatever code should be in the BeforeEach.

An example from our code below:

    beforeAll((done) => {
      // Mocking method from within Box file
      transferBoxPlanSpy = jest.spyOn(Box, 'transferPlanFromBox').mockImplementation(() => Promise.resolve());

      // Pulling data from MongoDB
      User.findOne({ user_name: 'testsurgeon1' }, (err, user) => {
        user.addMGSPermission();
        user.save(done);
      });
    });

    beforeEach(() => {
      planData2 = {
        user_name: 'hello1',
        laterality: 'right',
        plan_id: 'testplan42',
        order_number: '856-hd-02-l',
        file_id: '123456sbyuidbefui',
      };
    });

I hope my question isn't too vague. Thank you for your time!

Edit 1 I would like to point out that this code was not made by myself, but from one of our members on the software team. He puts the object inside of the BeforeEach, and the mocks inside of the BeforeAll.

My confusion is that it seems like all code can be put just into BeforeAll, with a few exceptions.

Stygian answered 4/2, 2019 at 13:19 Comment(0)
H
85

Both are used to set up whatever conditions are needed for one or more tests.

If you're certain that the tests don't make any changes to those conditions, you can use beforeAll (which will run once).

If the tests do make changes to those conditions, then you would need to use beforeEach, which will run before every test, so it can reset the conditions for the next one.

Unless the initialization is slow or computationally expensive, it may be safest to default to using beforeEach as it reduces the opportunity for human error, i.e. not realizing that one test is changing the setup for the next one. (Asynchronous network calls are a common -- though of course not the only -- use case for "slow" initialization where beforeAll is appropriate.)

The sample you showed is a good example of using both in combination -- the slow network call is put in beforeAll, so it only has to happen once; and the data object (which is presumably modified by the tests) is reset each time in beforeEach.

Heterophyte answered 4/2, 2019 at 13:43 Comment(4)
Perfect explanation! That makes more sense now. I forgot that the data structure could be altered, thus allowing the BeforeEach to reset before every test. Thank you!Stygian
@Stygian you can accept the answer.Orchestral
Do I even need to use beforeAll()? Wouldn't just placing it inside the describe work as well?Archduchy
No. describe just groups related tests together, it is not a substitute for beforeAll().Heterophyte
P
6

I know this is an old post but in the event that others come looking I would like to add some important information that I find surprised not to be mentioned here:

That beforeAll is specifically for ASYNCHRONOUS calls that need to complete before the tests are run.

In the original post the beforeAll function is redundant as it doesn't return a promise - you could simply place the function body immediately before your first describe or test

See the jest docs: https://jestjs.io/docs/setup-teardown

In some cases, you only need to do setup once, at the beginning of a file. This can be especially bothersome when the setup is asynchronous, so you can't do it inline. Jest provides beforeAll and afterAll to handle this situation.

E.g. the following returns a promise which will resolve before the tests proceed to run.

beforeAll(() => {
  return initializeCityDatabase();
});
Pretzel answered 21/1, 2022 at 21:21 Comment(1)
This is exactly what I was looking for. Did not see the point of using beforeAll rather than just having the code be inline.Ebon
V
1

BeforeAll - called only once before any of the test cases within a test suite

BeforeEach - called before each test case within a test suite

Viridi answered 2/4 at 18:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.