Jest: Context in before/afterEach calls

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

Do you want to request a feature or report a bug?

Bug. Related issues (Jasmine-related): https://github.com/facebook/jest/pull/3506 https://github.com/facebook/jest/issues/3505

What is the current behavior?

The this context is not shared over a single test: Before, during, and after.

If the current behavior is a bug, please provide the steps to reproduce and either a repl.it demo through https://repl.it/languages/jest or a minimal repository on GitHub that we can yarn install and yarn test.

/* eslint-env jest */

beforeEach(function () {
  this.hello = 'hi';
});

afterEach(function () {
  console.log(this.hello);
});

describe('context', () => {
  it('should work', function () {
    console.log(this.hello);
  });
});

What is the expected behavior?

I should see "hi" printed twice. Instead, I see undefined printed twice.

Please provide your exact Jest configuration and mention your Jest, node, yarn/npm version and operating system.

Jest 20.0.1.
Works on 19.0.0.


As an aside, I think it's best to recommend against this usage, especially as the style for JavaScript has moved toward () => {} functions rather than function() {} functions. Just dealing with some old code here :) I felt this issue might be helpful in documenting Jasmine's behavior and discussing next steps for Jest.

Most helpful comment

_It's not a bug, it's a feature_.
Seriously it is, Jest is not Jasmine and restricts context to test/before/after function scope. Use shared variables outside of test function scope.

let hello;
beforeEach(function () {
  hello = 'hi';
});

afterEach(function () {
  console.log(hello);
});

describe('context', () => {
  it('should work', function () {
    console.log(hello);
  });
});

All 11 comments

_It's not a bug, it's a feature_.
Seriously it is, Jest is not Jasmine and restricts context to test/before/after function scope. Use shared variables outside of test function scope.

let hello;
beforeEach(function () {
  hello = 'hi';
});

afterEach(function () {
  console.log(hello);
});

describe('context', () => {
  it('should work', function () {
    console.log(hello);
  });
});

This was quite the breaking change for us. I wish it had been mentioned in the release notes :-(.

Apologies, we rewrote Jasmine and this happened as a result of that :(

jest-codemods can now help people upgrade from older versions of Jest. See https://github.com/skovhus/jest-codemods/releases/tag/0.11.0

FYI @cpojer @thymikee @sarenji

Just wondering, is there any article with explanation why this was removed?

It would be great to get an explanation for the removal of this. To me, at least, this seems like a strange convention to enforce.

As Jest possibly moves towards TypeScript it might be worth revisiting this (or some similar solution for context). If you're using strict types (i.e. no implicit null/undefined) then you're forced to always initialize the local variable when you declare it or else always check that it's initialized:

let aVar:SomeType|undefined = undefined;

// Compiler doesn't know that beforeEach is is going to be called 
// so you have to define the variable above as possibly undefined...
beforeEach( ()=> { aVar = new SomeType; } );

test("A Test", ()=> {
    // Which means you have to ensure that the variable is defined 
    // wherever you use it.
    if (aVar !== undefined) { 
        // do  something with aVar...
    }
});

It's not necessarily a big deal especially if initializing the variable is trivial but if it's complex it can get slightly irritating.

@Ghirigoro

How about

let aVar!: SomeType;

beforeEach( ()=> { aVar = new SomeType; } );

test("A Test", ()=> {
    // do something with aVar without if-statement...
});

This way you have strict null checks for the whole project, but you can mitigate it for test cases on your own risk.

@yss14

That seems pretty good. I didn't realize you could use the bang operator on declarations. You learn something new every day. Thanks!

Yo, this needs to be fixed. How is it a "feature"? It's not necessarily a bug, but nobody gets any value out of the scoping not working as expected. It feels like bad design in user experience from the point of view of a user.

I don't get it. If I run with Jest experimental feature --detectLeak, it clearly says that I should not keep references to the global scope.

image

Am I losing something important?

Was this page helpful?
0 / 5 - 0 ratings