Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS / Karma testing: beforeEach not executed

I'm working on some TDD for AngularJS (another story altogether) and ran into a situation where my beforeEach calls are apparently not being executed. I reduced it down to the following example.

This works as evidenced by the fact that the console.log messages in beforeEach and it both appear:

describe('userApp', function(){ 
  beforeEach( function(){ 
    console.log("in beforeEach...");
  }); 

  it('should be able to log something', function(){ 
    console.log("in it...");
  }); 
});

This doesn't work, as evidenced by the fact that the console.log message in the beforeEach is NOT displayed and the it fails when attempting to $log.info and throws the error message: TypeError: Cannot read property 'info' of undefined

describe('userApp', function(){ 
  var $log;
  beforeEach(module('userApp', function($provide) {
    console.log("in beforeEach...");
    // Output messages
    $provide.value('$log', console);
  })); 
  it('should be able to log something', function(){ 
    console.log("in it...");
    $log.info("Using $log for logging...");
  }); 
});

I'm using Angular 1.3.15, karma 0.12.31, jasmine 2.3.4. Probably something obvious I'm overlooking...

EDIT: Michael Radionov's explanation is very helpful; however, I don't understand why this modified code still throws the same error.

describe('userApp', function(){ 
  console.log("starting TEST3");   <=== this prints
  var $log;
  beforeEach(function() {
    console.log("TEST3: in beforeEach...");   <=== this prints
    module('userApp', function($provide, _$log_) {
      $log = _$log_;
      console.log("TEST3: in beforeEach/module...");   <=== never executed
      // Output messages
      $provide.value('$log', console);
      $log.info("TEST3: calling $log in beforeEach...");
    })
  }); 
  it('should be able to log something', function(){ 
    console.log("TEST3: in it...");
    $log.info("TEST3: Using $log for logging...");  <=== $log undefined err
  }); 
});

Furthermore, it seems the code in "module('userApp'..." is never executed...?

like image 288
JESii Avatar asked Jul 05 '15 23:07

JESii


1 Answers

The reason your log message console.log("in beforeEach..."); is not being displayed is because it is not actually inside beforeEach, it is inside an anonymous function passed to a module(..) as an argument which is considered to be a module by angular-mocks. This module will be executed only when injection happens and at the same time you'll receive a log message in beforeEach..., but there is no any injection in your test, so it never happens. beforeEach fires anyway, you just didn't put console.log in the right place; it will work:

beforeEach(function () {

  console.log("in beforeEach...");

  module('userApp', function($provide) {
    // Output messages
    $provide.value('$log', console);
  });

});

Also it seems that you forgot to inject mocked $log into you test suite, your $log variable never gets any value, so it stays undefined as the error states.

describe('userApp', function(){ 

  var $log;

  beforeEach(function () {
    console.log("in beforeEach...");

    module('userApp', function($provide) {
      // Output messages
      $provide.value('$log', console);
    });

    // getting an instance of mocked service to use in a test suite
    inject(function (_$log_) {
      $log = _$log_;
    });

  }); 

  it('should be able to log something', function(){ 
    console.log("in it...");
    $log.info("Using $log for logging...");
  }); 

});

See the plunker: http://plnkr.co/edit/EirNEthh4CXdBSDAeqOE?p=preview

Docs:

  • angular.mock.inject
  • angular.mock.module
like image 195
Michael Radionov Avatar answered Oct 22 '22 04:10

Michael Radionov