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

[jest-plugin-set] Set variables should be created before beforeEach is called #71

Open
negativetwelve opened this issue Oct 18, 2017 · 5 comments

Comments

@negativetwelve
Copy link
Owner

Description

Nested set calls must ALL come before beforeEach in order to be set properly. Otherwise, it'll use the values from outer set calls which is incorrect

Screenshot

Test Plan

@negativetwelve negativetwelve self-assigned this Oct 18, 2017
@negativetwelve negativetwelve removed their assignment Dec 20, 2017
@bxt
Copy link

bxt commented Jul 24, 2018

@negativetwelve I wonder what this is about. When you mix in own beforeEach blocks and use values previously defined with set in them? Because this seems to work just fine:

import set from 'jest-plugin-set';

set('foo', () => 'outer');
set('bar', () => `bar with foo: ${foo}`);
set('baz', () => `baz with bam: ${bam}`);

describe('outer', () => {
  set('foo', () => 'inner');
  set('bam', () => 'yey');
  it('uses the inner foo for calculating bar', () => {
    expect(bar).toEqual('bar with foo: inner');
  });
  it('uses the inner bam for calculating baz', () => {
    expect(baz).toEqual('baz with bam: yey');
  });
});

@negativetwelve
Copy link
Owner Author

negativetwelve commented Jul 24, 2018

Hi @bxt, thanks for your comment. If I remember correctly, the issue comes from something like:

import set from 'jest-plugin-set';

describe('outer', () => {
  set('a', () => 1);
  set('b', () => a);

  beforeEach(() => {
    console.log(a, b);
  });

  describe('inner', () => {
    set('a', () => 5);

    beforeEach(() => {
      console.log(a, b);
    });

    it('returns the correct value', () => {
      expect(a + b).toEqual(10);
    });
  });
});

It will log:

1, 1
1, 1

when it should be:

1, 1
5, 5

and if I remember correctly, the test should fail on this and return 2 instead of 10. Let me know if you're seeing the same behavior.

(I wrote the code without testing, please excuse if there are small errors)

@bxt
Copy link

bxt commented Jul 24, 2018

Hey @negativetwelve, wow thank you for your fast answer! It also fails for me but slightly different. It outputs

1 1
5 1

And:

    Expected value to equal:
      10
    Received:
      6

So only the indirect calculation of b has the problem. Interestingly the beforeEach also messes with the assertion, because the bad value will be cached then.

(node v10.7.0, [email protected], [email protected])

I think one can get rid of all beforeEach uses with set though 😅

@negativetwelve
Copy link
Owner Author

oops you're right (I kept editing my responses haha). It's definitely a caching issue because of the order that the beforeEach are run in.

I stumbled upon this issue when using set to construct something like a user object and changing one value within a nested set of describe blocks. It wasn't too hard to work around but was definitely unexpected.

I mainly use set for variable assignment and beforeEach for actions and things like requests.

beforeEach(() => {
  fetch(url, params);
});

something like this ^

@timscott
Copy link

I ran into this also today. Here's another repro.

describe('', () => {
  set('a', () => x)
  beforeEach(() => {
    console.log(a);
  })
  describe('', () => {
    set('x', () => 1)
    test('', () => {
      expect(a).toEqual(1)
    })
  })
})

Fails with ReferenceError: x is not defined on the second line.

Pulling variables from inner contexts to use in beforeEach is definitely a useful pattern which can eliminate a lot of duplicate code. Something I always do in rspec.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants