[jest-plugin-set] Set variables should be created before beforeEach is called
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 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');
});
});
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)
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 😅
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 ^
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.