Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the purpose of `beforeEach` global in Jest?

I always find Jest-Enzyme test cases starting with a beforeEach global that resembles like the following:

describe('TEST BLOCK' () => {
  let wrapper;

  beforeEach(() => {
    wrapper = shallow(<Component />);
  });
));

The function inside the beforeEach global runs before each test inside the TEST BLOCK describe block. In this case, it shallow renders the Component and assigns to wrapper before running each test. I am not quite sure why do we do this in the first place. Are we not deliberatly slowing down the test runtime? Isn't it okay to render it once and assign it to wrapper? What is the purpose of the beforeEach here? Are there other scenarios where beforeEach is beneficial when testing React components?

like image 338
user117829 Avatar asked Aug 14 '19 15:08

user117829


People also ask

What is the use of beforeEach?

@BeforeEach is used to signal that the annotated method should be executed before each @Test method in the current test class.

What is the difference between beforeEach and beforeAll?

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.


2 Answers

If you have code that’s common across multiple tests, you can use beforeEach to do some setup before each test runs in order to avoid repetition. In this case, if you have multiple tests that shallow mount Component, you can move the shallow mount to a beforeEach, and the component will be mounted when every test runs. Generally you’ll want to pair this with an afterEach, where you call wrapper.unmount().

describe('tests', () => {
  it('does one thing', () => {
    const wrapper = shallow(<Component />);
    // ...test some things
    wrapper.unmount();
  });

  it('does another thing', () => {
    const wrapper = shallow(<Component />);
    // ...test something else
    wrapper.unmount();
  });

  it('does a third thing', () => {
    const wrapper = shallow(<Component />);
    // ...test a third thing
    wrapper.unmount();
  });
});

becomes:

describe('tests', () => {
  let wrapper;

  beforeEach(() => {
    wrapper = shallow(<Component />);
  });

  afterEach(() => {
    wrapper.unmount();
  });

  it('does something', () => {
    // ...test something
  });

  it('does something else', () => {
    // ...test something else
  });

  it('does another thing', () => {
    // ...test a third something
  });
});

beforeEach is referred to as the “setup” phase, and afterEach as the “teardown” phase.

Are we not deliberately slowing down the test runtime?

No, because you would have to shallow mount the component in each test anyway.

Isn’t it ok to render it once and assign it to wrapper?

Persisting a component (or any statefulness) across multiple tests can cause flaky tests, because (for example) you might get a different result if the tests are run in a different order. Any state (such as a mounted component) should be set up before each test and torn down after each test. This makes your tests completely independent from each other.

like image 87
helloitsjoe Avatar answered Sep 24 '22 01:09

helloitsjoe


Jest documentation recommends beforeEach for tests that consume a particular global state for each test, for example, resetting test data in a database before each test is run.

Note the following case:

If beforeEach is inside a describe block, it runs for each test in the describe block.

Using the same example where we have a database with test data, if your tests do not need the test data reset for each test, you can use beforeAll to run some code once, before any tests run.

like image 32
Peter Avatar answered Sep 25 '22 01:09

Peter