timtos timtos - 1 year ago 214
AngularJS Question

beforeEach not called via Karma/ Jasmine in an angularjs/ requirejs scenario

Running my unit tests locally works fine but on the build server the most stupid thing happens: Sometimes they pass, sometimes they don't. The main code:

define(['angmock', 'someMore'], function () {
describe('myController', function () {
beforeEach(function () {
console.log("Entry - Initializing modules...");
console.log("Exit - Initializing modules...");

var scope, controller;
beforeEach(inject(function ($rootScope, $controller) {
console.log("Entry - Creating scope...");

scope = $rootScope.$new();
controller = $controller('myController', {
$scope: scope

console.log("Exit - Creating scope...");

it('should test something', function () {
console.log("Entry - Test A");
scope.myImportantAssignment = variableName;
console.log("Exit - Test A");

In the build server log I can sometimes read:

TypeError: undefined is not an object (evaluating
'scope.myImportantAssignment = variableName')

And on the console I can read:

  • LOG: 'Entry - Initializing modules...'

  • LOG: 'Exit - Initializing modules...'

  • LOG: 'Entry - Test A'

That could show that the second beforeEach is not called at all and thus the scope is not initialized. But why? In my easy mind the processing should work like:

  • beforeEach 1

  • beforeEach 2

  • it

But that does not seem to be the case. Is there probably some problems with async? Any little hint is greatly appreciated as I can not use the tests at all if they are sometimes failing...

Answer Source

There are no race conditions that could explain the problem, the blocks are sync and always run in sequence. This may happen if the app silently fails to be bootstrapped and throws on inject.

There should be errors in the console, but PhantomJS is known for swallowing errors, changing Karma launcher to Chrome may improve error output.

Moving inject from beforeEach to it can also help to locate the problem, it makes the spec to fail not on failed expectation but on the error that makes this expectation to fail.

In unit tests the app units are tested, everything else should be mocked, having extra dependencies (Angular wrapper for Kendo UI) adds more moving parts to the specs.