How to test angular decorator functionality

I have a decorator in Angular that extends the functionality of the $ log service, and I would like to test it, but I see no way to do this. Here is the stub of my decorator:

angular.module('myApp') .config(function ($provide) { $provide.decorator('$log', ['$delegate', function($delegate) { var _debug = $delegate.debug; $delegate.debug = function() { var args = [].slice.call(arguments); // Do some custom stuff window.console.info('inside delegated method!'); _debug.apply(null, args); }; return $delegate }]); }); 

Note that this basically overrides the $log.debug() method, and then calls it after executing some custom stuff. In my application, this works, and I see the message 'inside delegated method!' in the console. But in my test, I do not get this output.

How can I test my decorator functions?
In particular, how can I add my decorator so that it really decorates my implementation of $log mock (see below)?

Here is my current test (mocha / chai, but this is not relevant):

 describe('Log Decorator', function () { var MockNativeLog; beforeEach(function() { MockNativeLog = { debug: chai.spy(function() { window.console.log("\nmock debug call\n"); }) }; }); beforeEach(angular.mock.module('myApp')); beforeEach(function() { angular.mock.module(function ($provide) { $provide.value('$log', MockNativeLog); }); }); describe('The logger', function() { it('should go through the delegate', inject(function($log) { // this calls my mock (above), but NOT the $log decorator // how do I get the decorator to delegate the $log module?? $log.debug(); MockNativeLog.debug.should.have.been.called(1); })); }); }); 
+7
angularjs testing angularjs-decorator
source share
1 answer

From the attached plunger ( http://j.mp/1p8AcLT ), the original version is the (mostly) untouched code provided by @jakerella (minor syntax adjustments). I tried to use the same dependencies that I could get from the original message. Note tests.js:12-14 :

 angular.mock.module(function ($provide) { $provide.value('$log', MockNativeLog); }); 

This completely cancels the built-in $log service, as you would expect, with the MockNativeLog implementation provided at the beginning of the tests because angular.mock.module(fn) acts as a configuration function for the mock module . Since the configuration functions are executed in FIFO order, this function captures the decorated $log service.

One solution is to re-apply the decorator inside this configuration function, as you can see from version 2 of the panel (the permalink will be nice, Plunker), tests.js:12-18 :

 angular.mock.module('myApp', function ($injector, $provide) { // This replaces the native $log service with MockNativeLog... $provide.value('$log', MockNativeLog); // This decorates MockNativeLog, which _replaces_ MockNativeLog.debug... $provide.decorator('$log', logDecorator); }); 
However, this is not enough. The @jakerella decorator defines a replacement for the $log service's debug method, as a result of which a later call to MockNativeLog.debug.should.be.called(1) will fail. The MockNativeLog.debug method MockNativeLog.debug no longer the spy provided by chai.spy , so sockets will not work.

Instead, notice that I created an additional spy in tests.js:2-8 :

 var MockNativeLog, MockDebug; beforeEach(function () { MockNativeLog = { debug: MockDebug = chai.spy(function () { window.console.log("\nmock debug call\n"); }) }; }); 

This code might be easier to read:

 MockDebug = chai.spy(function () { window.console.log("\nmock debug call\n"); }); MockNativeLog = { debug: MockDebug }; 

And this still does not constitute a good test result, just a performance test. This is a relief after you hit your head on the question “why not this job” for several hours.

Please note that I additionally reorganized the decorator function to the global scope so that I can use it in tests.js without the need to override it. It would be better to reorganize into the proper service using $provider.value() , but this task remained as an exercise for the student ... Or someone is less lazy than me .: D

+6
source share

All Articles