Jest: userContext not shared from beforeEach

Created on 28 May 2017  路  11Comments  路  Source: facebook/jest

I believe this is a bug

Current Behavior

Regression in 20.0.1. this is a fresh / empty object for every test. Values assigned to this in beforeEach are not accessible from tests.

I believe commit a9a322fa1afd97bef5117819bbbac9e810ae1169 introduced the regression.

Repro

https://repl.it/IUml/0

describe('userContext', function() {
  beforeEach(function() {
    this.foo = 'bar';
  });
  test('is accessible', function() {
    expect(this.foo).toEqual('bar');
  });
});

Expected Behavior

values assigned to this in a beforeEach function should be accessible to test functions. (Similar to how Jasmine works). This change is breaking the tests I recently migrated from Jasmine.

Versions, etc

Broken for Jest 20.0.4. Working for my yarn.lock that uses Jest 20.0.0.
Using yarn 0.24.6 on OSX Sierra.

Most helpful comment

Sorry to Frankenstein this, but I haven't seen an idiomatic way of replacing this pattern in jest anywhere in the docs. Are other people doing this?

...
let things;
let otherThing;
beforeEach(() => {
    things = initializeThings();
    otherThings = initionalizeOtherThings();
});
describe('etc etc', () => {})
...

This comes up a lot particularly when writing multiple tests against react components in a specific setup (e.g., given a component with these props, test a bunch of things).

All 11 comments

This was an intentional behavior change. Please don't rely on this in your tests.

Sorry to Frankenstein this, but I haven't seen an idiomatic way of replacing this pattern in jest anywhere in the docs. Are other people doing this?

...
let things;
let otherThing;
beforeEach(() => {
    things = initializeThings();
    otherThings = initionalizeOtherThings();
});
describe('etc etc', () => {})
...

This comes up a lot particularly when writing multiple tests against react components in a specific setup (e.g., given a component with these props, test a bunch of things).

I'd also love to know what the recommended replacement for the patterns introduced here is.

+1

You could use closured variables to achieve the same. Like:

describe('userContext', function() {
  let foo;
  beforeEach(function() {
    foo = 'bar';
  });
  test('is accessible', function() {
    expect(foo).toEqual('bar');
  });
});

You could use closured variables to achieve the same

Well the whole point of the by me above mentioned blogpost was to exactly avoid that <.<

@emilgoldsmith I missed the blog post, but also the answer might fix it for others that do not have an issue with using closured vars instead of this.

@emilgoldsmith I missed the blog post, but also the answer might fix it for others that do not have an issue with using closured vars instead of this.

Fair enough @robin-drexler

i would suggest using shared functions to generate setup data

const makeSomeData = (someValue) => {
  const someData = {a: 1, b: 2, c: 3};
  someData.someValue = someValue;
  return someData;
};

test('one', () => {
  const data = makeSomeData();
  // ...
});

test('two', () => {
  const data = makeSomeData('someValue');
  // ...
});

it's still highly shareable, doesn't have any state and very explicit.
Also this will work better with static typing, because beforeEach or reassigning variables make everything nullable which is super annoying to type

That works for a single piece of data, but I don't understand how it helps if you need to set up & teardown multiple async pieces for each test.

For instance, when using puppeteer:

let browser;
let page;

beforeAll((async () => {
    browser = await puppeteer.launch();
}));

beforeEach((async () => {
    page = await browser.newPage();

    await page.goto(`file://${require.resolve("../index.html")}`);
}));

afterEach(() => page.close());
afterAll(() => browser.close());

I need access to at least page in each test, and ideally browser. I've spent some time thinking about this and I can either repeat that in every test file, make multiple shared async functions & remember to pass values around correctly, or ... ?

All of the approaches I've been able to come up with seem really error-prone. If there's a better way I would love to use it. I hope I'm just missing something obvious.

Looks like https://github.com/facebook/jest/pull/4506 would do what I wanted, I expected beforeAll/afterAll to work like they do in mocha if not contained with a describe block. Hopefully that lands soon!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

SimenB picture SimenB  路  131Comments

udbhav picture udbhav  路  236Comments

RyanCCollins picture RyanCCollins  路  93Comments

maraisr picture maraisr  路  77Comments

paularmstrong picture paularmstrong  路  66Comments