Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

userContext not shared from beforeEach #3673

Closed
valthon opened this issue May 27, 2017 · 12 comments
Closed

userContext not shared from beforeEach #3673

valthon opened this issue May 27, 2017 · 12 comments

Comments

@valthon
Copy link

valthon commented May 27, 2017

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 a9a322f 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.

@cpojer
Copy link
Member

cpojer commented May 28, 2017

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

@cpojer cpojer closed this as completed May 28, 2017
@nihakue
Copy link

nihakue commented Jun 1, 2017

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).

@emilgoldsmith
Copy link
Contributor

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

@vzaidman
Copy link

+1

@robin-drexler
Copy link
Contributor

robin-drexler commented Aug 22, 2017

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');
  });
});

@emilgoldsmith
Copy link
Contributor

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 <.<

@robin-drexler
Copy link
Contributor

@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
Copy link
Contributor

@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

@aaronabramov
Copy link
Contributor

aaronabramov commented Aug 22, 2017

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

@tivac
Copy link

tivac commented Sep 29, 2017

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.

@tivac
Copy link

tivac commented Sep 29, 2017

Looks like #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!

@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 13, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants