In my real code, I encountered a problem that I wanted to demonstrate with a simple example.
The code below functions properly. I defined a variable in the root describe()
block that can be accessed in the it()
blocks of nested describe()
s.
describe('simple object', function () {
var orchard;
beforeEach(function () {
orchard = {
trees: {
apple: 10,
orange : 20
},
bushes: {
boysenberry : 40,
blueberry: 35
}
};
});
describe('trees', function () {
it ('should have apples and oranges', function() {
var trees = orchard.trees;
expect (trees.apple).toBeDefined();
expect (trees.orange).toBeDefined();
expect (trees.apple).toEqual(10);
expect (trees.orange).toEqual(20);
});
it ('should NOT have pears or cherries', function() {
var trees = orchard.trees;
expect (trees.pear).toBeUndefined();
expect (trees.cherry).toBeUndefined();
});
});
});
However, when I attempted to refactor my code to make it more concise, the following approach failed:
describe('simple object', function () {
var orchard;
beforeEach(function () {
orchard = {
trees: {
apple: 10,
orange : 20
},
bushes: {
boysenberry : 40,
blueberry: 35
}
};
});
describe('trees', function () {
var trees = orchard.trees; // TypeError: Cannot read property 'trees' of undefined
it ('should have apples and oranges', function() {
expect (trees.apple).toBeDefined();
expect (trees.orange).toBeDefined();
expect (trees.apple).toEqual(10);
expect (trees.orange).toEqual(20);
});
it ('should NOT have pears or cherries', function() {
expect (trees.pear).toBeUndefined();
expect (trees.cherry).toBeUndefined();
});
});
});
Inside the nested describe()
, the orchard
object is undefined, even though it's defined within the it()
blocks inside it.
Was this intentional by Jasmine's developers to prevent issues with resetting the object in beforeEach()
? How does it work? It seems like some sort of magic with apply()
or call()
, but I'm unsure...
--
On a related note, I can still streamline my code by adding another beforeEach()
block:
describe('simple object', function () {
var orchard;
beforeEach(function () {
orchard = {
trees: {
apple: 10,
orange : 20
},
bushes: {
boysenberry : 40,
blueberry: 35
}
};
});
describe('trees', function () {
var trees;
beforeEach(function() {
trees = orchard.trees;
});
it ('should have apples and oranges', function() {
expect (trees.apple).toBeDefined();
expect (trees.orange).toBeDefined();
expect (trees.apple).toEqual(10);
expect (trees.orange).toEqual(20);
});
it ('should NOT have pears or cherries', function() {
expect (trees.pear).toBeUndefined();
expect (trees.cherry).toBeUndefined();
});
});
});