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

狂风中的少年 提交于 2021-02-18 10:16:06

问题


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?


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/57497799/what-is-the-purpose-of-beforeeach-global-in-jest

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!