Should I make fun of ALL external services in angular?

I am currently starting with angular unit testing. Since the first controller I wanted looked like this, I was confused.

angular.module('sgmPaperApp') .controller('AccountCtrl', function ($mdToast, user, $firebaseArray, Ref) { var vm = this; vm.data = user; vm.save = saveUser; vm.comments = $firebaseArray(Ref.child('comments').orderByChild('person').equalTo(user.$id)); function saveUser() { vm.data.$save().then(function () { $mdToast.showSimple('Data saved'); }); } }); 

Should I make fun of all the external services that I use? In the end, this controller is not much more than external services and bullying firebaseArray can be difficult.

Thanks for your advice and help me get started with testing.

+4
source share
2 answers

You do not need to worry about what external dependencies do, they simply scoff at their API.

These are the only ones that I see. I'm going to suggest that you use jasmine

 var Ref, $firebaseArray, $mdToast, user, vm; beforeEach(function() { Ref = jasmine.createSpyObj('Ref', ['child', 'orderByChild', 'equalTo']); Ref.child.and.returnValue(Ref); Ref.orderByChild.and.returnValue(Ref); Ref.equalTo.and.returnValue(Ref); $firebaseArray = jasmine.createSpy('$firebaseArray').and.returnValue('comments'); $mdToast = jasmine.createSpyObj('$mdToast', ['showSimple']); user = jasmine.createSpyObj('user', ['$save']); user.$id = 'id'; module('sgmPaperApp'); // you should consider separate modules per "thing" inject(function($controller) { vm = $controller('AccountCtrl', { $mdToast: $mdToast, user: user, $firebaseArray: $firebaseArray, Ref: Ref }); }); }); 

Then you can easily create your tests.

 it('assigns a bunch of stuff on creation', function() { expect(vm.data).toBe(user); expect(vm.comments).toEqual('comments'); // that what the mock returns expect(Ref.child).toHaveBeenCalledWith('comments'); expect(Ref.orderByChild).toHaveBeenCalledWith('person'); expect(Ref.equalTo).toHaveBeenCalledWith(user.$id); expect($firebaseArray).toHaveBeenCalledWith(Ref); }); 

You can even test promise-based methods like saveUser

 it('saves the user and makes some toast', inject(function($q, $rootScope) { user.$save.and.returnValue($q.when()); // an empty, resolved promise vm.saveUser(); expect(user.$save).toHaveBeenCalled(); expect($mdToast.showSimple).not.toHaveBeenCalled(); // because the promise hasn't resolved yet $rootScope.$apply(); // resolves promises expect($mdToast.showSimple).toHaveBeenCalledWith('Data saved'); })); 
+5
source

So, to answer the question, we need to consider what we are actually trying to do. If we try unit test , then yes, we need to make fun of all the dependencies.

Mocking your addictions will not be easy. You only need to make fun of what you use.

For example, $firebaseArray launched as a function that receives a parameter, we know that a lot:

 var mockFirebaseArray = function(ref) { }; 

Then, before we finish, we need to make fun of Ref :

 var mockRef = { child: function(path) { this.orderByChild = function(path) { this.equalTo = function(val) { }; return this; }; return this; } }; 

With these things, we can decide how the test will go. We could just use spies. Or we could set local variables that we can assert later on in our path.

Spies are my preferred method, because you can even verify that they were called with specific values:

 expect(mockFirebaseArray).toHaveBeenCalled(); expect(mockRef.child).toHaveBeenCalledWith('comments'); 

Now, if you want to write an integration test that is different. In this case, I still use spyware, but you are actually executing these dependencies. Generally speaking, there is no need to test your dependencies, because they must also be tested in isolation. In addition, there is no need to check other people's APIs if they are from reliable sources.

+1
source

All Articles