Consider what you would do if you had developed it using TDD. It aligns with Sam's suggestions, but here are some specific examples:
Testing Controllers
- Begin by writing a test expecting a deleteClick to be present.
- Check that deleteClick sets the loading state (confirm processing = true)
- Verify if a service is injected into the controller (peopleNotesSrv)
- Ensure deleteClick calls the service (using spies as mentioned earlier)
- Confirm that $scope.noteId and other $scope.params are available and set
These steps cover the Controller testing aspect. Any criteria related to failures or errors should be tested in a Service.spec file. For service details, refer to these examples.
Service Testing
- Validate the existence of deleteNote method
- Test scenarios with incorrect number of arguments supplied
- Perform positive tests (e.g., noteId = 5)
- Conduct negative tests
- Verify proper execution of callbacks
...and more.
Validating controllers may not be logical because then every Controller would require such testing. By isolating the Service as a separate Unit of Test and ensuring it meets all criteria, you can utilize it without additional testing. This concept is similar to assuming jQuery features work as expected without individual testing, just like Angular jQLite :)
UPDATE:
Triggering fails in controller tests upon service call
To illustrate this, let's create a scenario where we want our Service Test to fail when an incorrect number of arguments is provided:
describe('Service: peopleNoteSrv', function () {
// load the service's module
beforeEach(module('angularControllerServicecallApp'));
// instantiate service
var peopleNoteSrv;
beforeEach(inject(function (_peopleNoteSrv_) {
peopleNoteSrv = _peopleNoteSrv_;
}));
it('should throw error on incorrect argument count', function () {
expect(function() { peopleNoteSrv.deleteNote('justOneParameter'); }).toThrow();
});
});
In order for the above test to pass, add the error throwing logic in our service method:
angular.module('angularControllerServicecallApp')
.service('peopleNoteSrv', function peopleNoteSrv() {
this.deleteNote = function(param1, param2, param3) {
if(arguments.length !== 3)
throw Error('Invalid number of arguments supplied');
return "OK";
};
});
Additionally, let's create two demo controllers - FirstCtrl functioning correctly, while SecondCtrl should fail:
angular.module('angularControllerServicecallApp')
.controller('FirstCtrl', function ($scope, peopleNoteSrv) {
$scope.doIt = function() {
return peopleNoteSrv.deleteNote('param1', 'param2', 'param3');
}
});
angular.module('angularControllerServicecallApp')
.controller('SecondCtrl', function ($scope, peopleNoteSrv) {
$scope.doIt = function() {
return peopleNoteSrv.deleteNote('onlyOneParameter');
}
});
Both controllers have the following test scenario:
it('should call Service properly', function () {
expect(scope.doIt()).toBe("OK");
});
Karma output will indicate any mismatches between expected and actual results. Specifically identifying which part of the code needs attention, like updating SecondCtrl. This approach applies to any tests involving the Service method.
I hope this explanation clarifies your query.