jeudi 20 août 2015

Mocking provider, injecting stuff

I have a somewhat complicated scenario here, I'll try my best to explain it, sorry if it's feels confusing.

Say, I have a contrived provider sitting in module aptly named core, let's call it actionProvider, it can register actions and then later invoke them. And I use it like this:

 // registering an action in m1 module
 angular.module('m1').config((actionProvider)=> {

     actionProvider.reg('myAction', { $fn: myActionFn });

     myActionFn.$inject = ['$modal'];  

     function myActionFn($modal) {
         $modal.open()    // when action invoked it opens a modal dialog 
     } 
 })


// now somewhere else I invoke that previously registered action 
angular.module('m2').controller('myCtrl', (action)=> {
  action.invoke('myAction');    // and that calls $fn with $modal.open()
})

And this works perfectly. Now, let's say I have to test actionProvider in a module that has no access to source code of actionProvider. Means I completely need to mock it. Ok. Let's try doing this:

 angular.module('core', []).provider('action', function() {
     let self = this;
     self.actions = [];

     self.$get = ()=> { return self }; // essential function that every provider has

     // registering action just pushes it into the array of actions,
     // remember this is a fake provider
     self.reg = (action)=> {
        self.actions.push(action) 
     };

     // yet even though it's a fake it still needs to be able to invoke actions
     self.invoke = (actionName) {
         // so here I need to find specified action in the array and invoke it
     };
})

Finding the right action in self.actions is easy. But how do I invoke its $fn correctly? How do I tell injector to find all the objects that's been injected (in the case of myAction it would be $modal service)

Aucun commentaire:

Enregistrer un commentaire