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...?
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:
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