Previously when I was writing angular apps, I used to do
angular.module('ngApp', ['all', 'required', 'ng*', 'dependencies'])
in my app.js
and then inside services/
and controllers
, I could simply do:
angular.module('ngApp')
I have a repo to demonstrate that.
But then I saw the angular-seed/
, the way implemented was,
in controllers/
angular.module('appControllers', ['dependencies'])...
in services/
angular.module('appServices', ['dependencies'])..
in app.js
angular.module('ngApp', ['ng*', 'appControllers', 'appSrvices'])..
I had no issue with design, infact I thought it was good, since evrything was dependency injected as well as modular.
I have a situation where I have a services/movie.js
that has
angular.module('myAppServices', ['ngResource']).factory(..)
and services/config.js
angular.module('myAppServices').factory(..)
But while writing tests with karma and jasmine. In the karma.conf.js,
I had
files: ['usual', 'bower_components/angular-*.js', 'app/services/**/*.js', '..']
but the problem was config.js got loaded before movie.js and there were errors, myAppServices
is not loaded or mis-spelt.
The way I fixed it was I did:
files: ['..', 'app/services/movie.js', 'app/services/config.js']
I have set up a github repo for this too. Here is the controller test file and here is the karma.conf.
I want to know what can be the possible approaches to take such modular approach, without having to specify the order in which the files are to be loaded for my tests.
And this is my first unit test, and its failing:
Error: Unexpected request: GET https://api.themoviedb.org/3/configuration?api_key=2e329c92227ed8be07944ae447c9426f
Expected GET https://api.themoviedb.org/3/movie/top_rated?api_key=2e329c92227ed8be07944ae447c9426f
It would be helpful if I could get some help in fixing that too.
The test
describe('Controllers', function() {
beforeEach(module('myApp'));
beforeEach(module('myAppServices'));
describe("MoviesCtrl", function() {
var scope, ctrl, httpBackend;
beforeEach(inject(function($httpBackend, $rootScope, _$controller_, Movie, Config) {
httpBackend = $httpBackend;
ctrl = _$controller_;
scope = $rootScope.$new();
}));
it("should return a list of movies", function() {
var data = {results: [{name: "Abc"}, {name: "Def"}]};
httpBackend.
expectGET("https://api.themoviedb.org/3/movie/top_rated?api_key=2e329c92227ed8be07944ae447c9426f").
respond(data);
ctrl('MoviesCtrl', { $scope: scope });
httpBackend.flush()
expect(scope.image).toEqual("https://api.themoviedb.org/3/");
});
});
});
conf. file
module.exports = function(config) {
config.set({
basePath: './',
frameworks: ['jasmine'],
files: [
'app/bower_components/angular/angular.js',
'app/bower_components/angular-mocks/angular-mocks.js',
'app/bower_components/angular-resource/angular-resource.js',
'app/bower_components/angular-route/angular-route.js',
'app/services/movie.js',
'app/services/config.js',
'app/controllers/*.js',
'app/app.js',
'unit-tests/**/*.js'
],
exclude: [
'app/**/*.min.js'
],
preprocessors: {
},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false
});
};
UPDATE
I have figured out the error in test, I had to mock the other http request for the configuration. thanks to @Phil.
This is my test now:
describe('Controllers', function() {
beforeEach(module('myApp'));
beforeEach(module('myAppServices'));
describe("MoviesCtrl", function() {
var scope, httpBackend;
var config_data = { images: { base_url: "http://tmdb.com/t/p", backdrop_sizes: ["w300", "w500"]}},
movie_data = {results: [{name: "Abc"}, {name: "Def"}]};
beforeEach(inject(function($httpBackend, $rootScope, $controller) {
httpBackend = $httpBackend;
scope = $rootScope.$new();
httpBackend.
expectGET("https://api.themoviedb.org/3/configuration?api_key=2e329c92227ed8be07944ae447c9426f").
respond(config_data);
httpBackend.
expectGET("https://api.themoviedb.org/3/movie/top_rated?api_key=2e329c92227ed8be07944ae447c9426f").
respond(movie_data);
$controller('MoviesCtrl', { $scope: scope });
}));
it("should return a list of movies", function() {
expect(scope.image).toEqual({})
httpBackend.flush();
expect(scope.image.backdrop_size).toEqual("w300");
});
});
});
Although I am not sure if this is the right test to do :P . Something like a VCR would be helpful.