Reputation: 792
i have created a factory for the lodash library in my angular app like so:
angular.module('lodash',[]).service('_', function(){
var _ = window._;
// i am delete the _ property on the window
// so that i m enforced to dependency inject
// lodash each time i want to use it
// instead of using the global lodash library
delete window._;
return _;
});
Now I want to test my module service and i m using the following test
describe('lodash', function() {
// load the utilities module
beforeEach(module('lodash'));
describe('_', function() {
it('should be defined', inject(function(_) {
expect(_).not.toBe(null);
}));
it('should have toArray() defined', inject(function(_) {
expect(_.toArray).toBeDefined();
}));
});
});
This 2nd test is not succeeding. The only way to make that work is to take away the following line from my service implementation.
delete window._;
My question comes here: Since delete operator only deletes the property from the window object and not the original reference why does deleting window._ break the test and the _ object comes empty in the tests?
Upvotes: 2
Views: 2146
Reputation: 411
After each test you jast need to return back $window._
This code should work correctly:
describe('lodash', function() {
var factory;
// load the utilities module
beforeEach(module('lodash'));
beforeEach(inject(function (___) {
factory = ___;
}));
afterEach(inject(function (_$window_) {
_$window_._= factory;
}));
describe('_', function() {
it('should be defined', function() {
expect(factory).toBeDefined();
});
it('should have toArray() defined', function () {
expect(factory.toArray).toBeDefined();
});
it('default keys method ->', function () {
expect(factory.keys({"key1": "value1", "key2": "value2", "key3": "value3"})).toEqual(["key1","key2","key3"]);
});
});
});
Upvotes: 1
Reputation: 157
I remember having similar problem. Not sure if the problem is exactly the same, but I solved it copying the properties of lodash in a new object, which I then returned from the factory :
function lodash($window) {
var lodashLib = $window._;
var _ = {};
delete( $window._ );
// Instead of using directly what I got from the window object, I copy its properties
// I cannot explain why this works better, but it solved the problem for me
angular.extend(_, lodashLib);
return _;
}
Secondly, I think you should be careful with testing not.toBe(null)
, toBeDefined()
might be better (there are a lot of really precise ways to test things with Jasmine). Lastly, for your second test, I believe the proper test should be expect(typeof _.toArray).toBe('function');
, which is a bit more specific than just being defined :)
I hope I answered your question, even if my knowledge of unit tests is in general pretty lackluster.
Upvotes: 1