You shouldn't be testing private/internal methods that are not available to the outside world(imho).
Some resources on the subject (for & against):
With that said, you are exposing getImageStacks
on the controller - so it isn't a private method. If you were to log out the result of instantiating the controller in your test suite, you should see something of the sort:
{ getImageStacks: function }
(init()
in your case, is just an alias for getImageStacks
(aka there is no need for the init
method - you could just call getImageStacks
and be done with it)).
Anyway, to write some tests;
First of, you should stub
out the ImageService
as we are not interested in the internal implementation of said service, we are only ever interested in the communication going from the controller to the service. A great library for stubbing/mocking/spying is sinonjs - get it, you won't regret it.
In the beforeEach
I would suggest you do something like this:
// Stub out the ImageService
var ImageService = {
fetchImageStacks: sinon.stub(),
setImageStacks: sinon.stub()
};
var $scope, instantiateController;
beforeEach(function () {
// Override the ImageService residing in 'your_module_name'
module('your_module_name', function ($provide) {
$provide.value('ImageService', ImageService);
});
// Setup a method for instantiating your controller on a per-spec basis.
instantiateController = inject(function ($rootScope, $controller, $injector) {
ctrl = $controller('ImageController', {
$scope: $rootScope.$new(),
// Inject the stubbed out ImageService.
ImageService: $injector.get('ImageService')
});
});
});
Now you have a stubbed out ImageService to test calls against, and a method to instantiate your controller with the dependencies passed into it.
Some example specs you can run;
it('calls the ImageService.fetchImageStacks method on init', function () {
instantiateController();
expect(ImageService.fetchImageStacks).to.have.been.calledOnce;
});
it('calls the ImageService.setImageStacks on success', inject(function ($q, $timeout) {
ImageService.getImageStacks.returns($q.when('value'));
instantiateController();
$timeout.flush();
expect(ImageService.setImageStacks).to.have.been.calledOnce.and.calledWith('value');
}));
I hope that will suffice and answer your questions on;
- If/when you should/shouldn't test internal implementation.
- How to test the initialisation of the controller.
- How to test methods of an injected service.