If you have multiple beforeEach
's, will they always run one after another?
beforeEach(function() {});
beforeEach(function() {});
beforeEach(function() {});
beforeEach(function() {});
beforeEach(function() {});
It seems that they will. I tried testing it with my code:
describe('Directive: Statement', function() {
var el, scope, statements;
beforeEach(module('simulatedSelves'));
beforeEach(module('templates'));
beforeEach(inject(function($compile, $rootScope) {
console.log(1);
scope = $rootScope.$new();
statements = [];
scope.statement = {
text: 'test',
arr: []
};
scope.statement.parent = statements;
statements.push(scope.statement);
el = angular.element('<statement statement=statement></statement>');
$compile(el)(scope);
scope.$digest();
}));
beforeEach(function() {
var counter = 0;
console.log(2);
for (var i = 0; i < 1000000; i++) {
counter++;
}
console.log(counter);
});
beforeEach(function() {
console.log(3);
});
it('test statement has correct properties', function() {
// stuff
});
});
It logs:
1
2
1000000
3
Since the beforeEach
with the long for
loop logs its stuff out before the one that logs 3
, I'm thinking that the beforeEach
's run synchronously. Is that true?
Jasmine supports three ways of managing asynchronous work: async / await , promises, and callbacks. If Jasmine doesn't detect one of these, it will assume that the work is synchronous and move on to the next thing in the queue as soon as the function returns.
JasmineJS - beforeEach() Advertisements. Another notable feature of Jasmine is before and after each function. Using these two functionalities, we can execute some pieces of code before and after execution of each spec. This functionality is very useful for running the common code in the application.
Note that you can use both before() and beforeEach() together. Mr. J. J.
Yes, all beforeEach
s will execute in the order you define.
If you drill into Jasmine, you eventually get to this definition:
Suite.prototype.beforeEach = function(fn) {
this.beforeFns.unshift(fn);
};
As you add describe
s, Suite
s get generated and nested. Each Suite
is initialized with this.beforeFns = []
, which is added to as you can see. Note that unshift
adds to the left side of the array, so you'd expect later-defined beforeEach
s to be run first. That's fixed later when Jasmine walks up the child suite's parents, gathers all beforeEach
lists, and then reverses them to run in the order you want.
var beforeAndAfterFns = function(suite) {
return function() {
var befores = [],
afters = [];
while(suite) {
befores = befores.concat(suite.beforeFns);
afters = afters.concat(suite.afterFns);
suite = suite.parentSuite;
}
return {
befores: befores.reverse(),
afters: afters
};
};
};
As Dan points out, we've so far assumed that all of your beforeEach
s are synchronous. As of Jasmine 2, you can set up asynchronous beforeEach
s like so:
beforeEach(function(done) {
setTimeout(function() {
console.log('Async');
done();
}, 1000)
});
At runtime, Jasmine sends you the done
function and executes asynchronously if your function takes an argument. (Function.length returns the number of arguments the function expects).
for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) {
var queueableFn = queueableFns[iterativeIndex];
if (queueableFn.fn.length > 0) {
attemptAsync(queueableFn);
return;
} else {
attemptSync(queueableFn);
}
}
attemptAsync
waits for you to call done()
before the QueueRunner
moves on to the next beforeEach
hook, so ordering still works! Pretty neat.
describe('beforeEach', function() {
var data = null;
beforeEach(function() { data = []; });
beforeEach(function() { data.push(1); });
beforeEach(function(done) {
setTimeout(function() {
data.push('Async');
done();
}, 1000);
});
beforeEach(function() { data.push(2); });
beforeEach(function() { data.push(3); });
it('runs in order', function(){
expect(data).toEqual([1, 'Async', 2, 3]);
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With