angularJS+requireJS并集成karma测试实践

最近在为下一个项目做前端技术选型,Angular是必须要用的(BOSS指定,个人感觉也不错,开发效率会很高)。由于需要加载的JS很多,所以打算看看angular和requirejs一起用会怎么样。在git上有一个模板加《angular-requirejs-seed》,这个对angular和requirejs结合有很好的指导。但是他把karma的单元测试js放在项目中了,我更喜欢放在test目录下。

由于为linux下没有截图工具,就手打了。求Linux下好用的截图工具分享。要用karma测试首先使用karma init命令生成测试文件karma.conf.js。

在项目下输入命令karma init  

  Which testing framework do you want to use? jasmine  

  Do you want to use Require.js?  yes            注意:按上下键就可以选择

  Do you want to capture any browsers automatically?   Chrome  注意,可以选多个

  What is the location of your source and test files?  app/**/**/*.js  enter键  app/app.js  enter键  app/require-config.js  enter键 test/**/*Spec.js    这里的路径更加实际项目情况来确定。可以多个路径。

  Should any of the files included by the previous patterns be excluded ? enter键跳过。

  Do you wanna  generate a bootstrap file for RequireJS? yes

  Do you want karma to watch all the files and run the tests on change? yes

 在这些步骤完成之后,会在根目录生成叫做karma.conf.js和test-main.js的两个文件。由于习惯,我喜欢将karma.conf.js放入test目录下,这时需要将karma.conf.js的basePath改为"..";这里的test-main.js文件就是karma在测试的代替app下的require-config.js的文件,所以test-main.js文件和require-config的内容几乎完全一样,只是由于位置不一样,所以在test-main中增加一个baseUrl.

 1 var allTestFiles = [];

 2 var TEST_REGEXP = /(spec|test)\.js$/i;

 3 

 4 Object.keys(window.__karma__.files).forEach(function(file) {

 5   if (TEST_REGEXP.test(file)) {

 6     // Normalize paths to RequireJS module names.

 7     allTestFiles.push(file);

 8   }

 9 });

10 

11 require.config({

12   // Karma serves files under /base, which is the basePath from your config file

13   baseUrl: '/base/app',

14   paths: {

15     angular: 'bower_components/angular/angular',

16     angularRoute: 'bower_components/angular-route/angular-route',

17     angularMocks: 'bower_components/angular-mocks/angular-mocks',

18     angularCookies:'bower_components/angular-cookies/angular-cookies',

19     angularResource:'bower_components/angular-resource/angular-resource'

20   },

21   shim: {

22     'angular' : {'exports' : 'angular'},

23     'angularRoute': ['angular'],

24     'angularCookies': ['angular'],

25     'angularResource': ['angular'],

26     'angularMocks': {

27       deps:['angular'],

28       'exports':'angular.mock'

29     }

30   },

31   priority: [

32     "angular"

33   ],

34   // dynamically load all test files

35   deps: allTestFiles,

36 

37   // we have to kickoff jasmine, as it is asynchronous

38   callback: window.__karma__.start

39 });

40 require([

41     'angular',

42     'app'

43   ], function(angular, app) {

44     var $html = angular.element(document.getElementsByTagName('html')[0]);

45     angular.element().ready(function() {

46       // bootstrap the app manually

47       angular.bootstrap(document, ['cxriaApp']);

48     });

49   }

50 );
test-main.js

 

 1 'use strict';

 2 

 3 if(window.__karma__) {

 4     var allTestFiles = [];

 5     var TEST_REGEXP = /spec\.js$/;

 6 

 7     var pathToModule = function(path) {

 8         return path.replace(/^\/base\/app\//, '').replace(/\.js$/, '');

 9     };

10 

11     Object.keys(window.__karma__.files).forEach(function(file) {

12         if (TEST_REGEXP.test(file)) {

13             // Normalize paths to RequireJS module names.

14             allTestFiles.push(pathToModule(file));

15         }

16     });

17 }

18 

19 require.config({

20     paths: {

21         angular: 'bower_components/angular/angular',

22         angularRoute: 'bower_components/angular-route/angular-route',

23         angularMocks: 'bower_components/angular-mocks/angular-mocks',

24     angularCookies:'bower_components/angular-cookies/angular-cookies',

25     angularResource:'bower_components/angular-resource/angular-resource',

26     uiBootstrap:'bower_components/angular-bootstrap/ui-bootstrap'

27     },

28     shim: {

29         'angular' : {'exports' : 'angular'},

30         'angularRoute': ['angular'],

31         'angularCookies': ['angular'],

32         'angularResource': ['angular'],

33         'angularMocks': {

34             deps:['angular'],

35             'exports':'angular.mock'

36         }

37     },

38     priority: [

39         "angular"

40     ],

41     deps: window.__karma__ ? allTestFiles : [],

42     callback: window.__karma__ ? window.__karma__.start : null,

43     baseUrl: window.__karma__ ? '../app' : ''

44 });

45 

46 require([

47     'angular',

48     'app'

49     ], function(angular, app) {

50         var $html = angular.element(document.getElementsByTagName('html')[0]);

51         angular.element().ready(function() {

52             // bootstrap the app manually

53             angular.bootstrap(document, ['cxriaApp']);

54         });

55     }

56 );
require-config

下面是为测试路由的代码:

 1 /**

 2  * Created by taox on 15-6-19.

 3  */

 4 'use strict';

 5 

 6 define([

 7   'angular',

 8   'angularMocks',

 9   'app'

10 ], function() {

11   describe('Routes test', function() {

12     var location,route,rootScope;

13     beforeEach(module('cxriaApp'));

14     beforeEach(inject(function(_$location_,_$route_,_$rootScope_){

15       location = _$location_;

16       route = _$route_;

17       rootScope = _$rootScope_;

18     }));

19     describe('index route', function(){

20       var httpbackend;

21       beforeEach(inject(function($httpBackend){

22         httpbackend = $httpBackend;

23       }));

24       it('should load the homepage on successful load of /.', inject(function() {

25         httpbackend.expectGET('./partials/home/home.html').respond('200','main HTML');

26         location.path('/');

27         rootScope.$digest();

28         expect(route.current.controller).toBe('HomeCtrl');

29       }));

30       it('should redirect to the homepage on non-existent route',function(){

31         httpbackend.expectGET('./partials/home/home.html').respond('200','main HTML');

32         location.path('/non-existent-path');

33         rootScope.$digest();

34         expect(route.current.controller).toBe('HomeCtrl');

35       });

36       it('should redirect to room page on successful load of /room/1',function(){

37         httpbackend.expectGET('./partials/room/room.html').respond('200','main HTML');

38         location.path('/room/1');

39         rootScope.$digest();

40         expect(route.current.controller).toBe('RoomCtrl');

41       })

42     });

43   });

44 

45 });
RouteSpec

对于karma再测试angular的指令时,为现在遇到一个很蛋疼的问题,那就时在当指令使用templateUrl时,需要karma-ng-html2js-preprocessor才能测试,这时需要修改karma.conf.js.

1.在files中增加模板的地址如:'app/directives/chatroom/*.html',

2.在plugins中增加''karma-ng-html2js-preprocessor',

3.在preprocessors中增加'app/directives/chatroom/*.html':['ng-html2js']

在这3步完成后,下面是我的测试文件,也通过测试了。

 1 /**

 2  * Created by taox on 15-6-30.

 3  */

 4 describe('Unit:Directives',function(){

 5   var scope,compile;

 6 

 7   beforeEach(module('chatroomDirective'));

 8   beforeEach(module('directives/chatroom/chatroom.html'));

 9   beforeEach(inject(function($compile,$rootScope){

10     compile = $compile;

11     scope = $rootScope;

12   }));

13 

14   it('should content words 发送',function(){

15     var ele = angular.element('<chatroom></chatroom>');

16     var chatroom = compile(ele)(scope);

17     scope.$digest();

18     expect(chatroom.html()).toContain('发送');

19   });

20 });
chatroomDirectiveSpec

但是如果我在模板中绑定了ng-controller,则会报错。有人知道怎么将controller绑定到模板上吗?如果有知道的,求在http://www.cnblogs.com/towersxu/p/4600298.html 上面留言。下面是为尝试将controller绑定到模板上的方法:

/**

 * Created by taox on 15-6-30.

 */

describe('Unit:Directives',function(){

  var scope,compile,chatroomCtrl;



  beforeEach(module('chatroomDirective'));

  beforeEach(module('directives/chatroom/chatroom.html'));

  beforeEach(inject(function($compile,$controller,$rootScope){

    compile = $compile;

    scope = $rootScope.$new();

    chatroomCtrl = $controller('chatroomCtrl',{$scope:scope,$routeParams:{roomId:'1'}});

  }));



  it('should display words 发送',function(){

    var ele = angular.element('<chatroom></chatroom>');

    var chatroom = compile(ele)(scope);

    scope.$digest();

    expect(chatroom.html()).toContain('发送');

  });

});

  错误提示为:Unknown provider:$routeParamsProvider<- $routeParams <-chatroomCtrl.我在测试controller的时候就不会出现这个错误。

你可能感兴趣的:(AngularJS)