Jest, data in one test bleeding to another

Viewed 380

I have been facing this issue with jest, where the data i set in one test is creeping into another test and causing it to fail.

Let me try to show some code

spec.ts

const MOCK_PRODUCT = require('../dummydata/dummydata.json');

describe('function 1', () => {
  test('something', () => {
    const productData = MOCK_PRODUCT;
    expect(...) // works fine
  });

  test('something else', () => {
    const productData = MOCK_PRODUCT;
    productData.someField.push({...})
    expect(...) // works fine
  });
});

describe('function 2', () => {
  test('something more', () => {
    const productData = MOCK_PRODUCT;
    expect(...) // fails
  });
});

My test file goes like this. There is a describe block for each function and multiple tests inside the describe block.

What i observe is that, when i changed the productData in second test as you see above, the changed data is available in all the tests in the next describe block, causing them to fail.

Am i doing something wrong? is something missing?

2 Answers

Unfortunately that is by design. The script is just run from top to bottom. beforeAll, beforeEach, afterEach and afterAll functions could help you to factor out some code from your test methods.

You can also use the cloneDeep function from lodash to make an completely independent copy of the test data before each test runs.

const MOCK_PRODUCT = require('../dummydata/dummydata.json');
const _ = require('lodash'),
let productData = undefined;
beforeEach(() => {
  productData = _.cloneDeep(MOCK_PRODUCT);
})

describe('function 1', () => {
  test('something', () => {
    expect(...) // works fine
  });

  test('something else', () => {
    productData.someField.push({...})
    expect(...) // works fine
  });
});

describe('function 2', () => {
  test('something more', () => {
    expect(...) // fails
  });
});

It seems MOCK_PRODUCT is a object, then when you set const productData = MOCK_PRODUCT;, the productData is a referent to MOCK_PRODUCT. This means if you update producData content, MOCK_PRODUCT content also be updated.

In the previous test, you update productData object, then the next test will not working as your expected.

A simple way to avoid it is to stop using referent way, just clone to a new object for every test.

const productData = {...MOCK_PRODUCT};

My recommendation, define productData variable at the top level, assign cloned MOCK_PRODUCT for it in beforeEach. Then use productData in each test.

Related