单元测试角度/离子项目

Unit testing angular/Ionic project

本文关键字:子项目 单元测试      更新时间:2023-09-26

我有一个非常简单的控制器,看起来像这样。

timeInOut.controller('timeInOutController', function($scope, $filter, $ionicScrollDelegate){
    ... 
});

每当我试图为它创建一个单元测试时,就像这样…

(function() {
'use strict';
    var scope, controller, filter;
    describe('timeInOutController', function () {
        beforeEach(module('common.directives.kmDateToday'));
        beforeEach(inject(function ($rootScope, $controller, $filter) {
            scope = $rootScope.$new();
            filter = $filter;
            controller = $controller('timeInOutController', {
                $scope: scope
            });
        }));
        describe('#date setting', function(){
            ...
        });
    });
})();

我得到错误:

[$injector:unp]未知提供程序:$ionicCrollDelegateProvider<-$ionicCrollDelegate

很明显,在我的例子中,我并没有试图将$ionicScrollDelegate注入测试中,这只是因为我已经尝试了很多种方法,但都没有成功,也不知道该包括哪种失败的尝试。

此外,在我的karma.conf.js文件中,我还包括ionic.bundle.jsangular-mocks.js库/文件。

我可以成功地对任何不使用$ionic的东西进行单元测试,所以我知道我的测试框架设置正确,问题是注入任何与ionic相关的东西。

如果要通过angular实例化控制器,则需要传入所有参数。通过添加参数,你告诉angular,任何时候你创建这些控制器时,我也需要这些东西,因为我依赖它们。

因此,我的建议是模拟这些依赖关系的一些表示,并在创建控制器时注入它们。它们不一定(也不应该)是单元测试的实际服务。Jasmine让你能够创建间谍对象,你可以注入,这样你就可以验证这个单位的行为。

(function() {
'use strict';
    var scope, controller, filter, ionicScrollDelegate;
    describe('timeInOutController', function () {
        beforeEach(module('common.directives.kmDateToday'));
        beforeEach(inject(function ($rootScope, $controller, $filter) {
            scope = $rootScope.$new();
            filter = $filter;
            // func1 and func2 are functions that will be created as spies on ionicScrollDelegate
            ionicScrollDelegate = jasmine.createSpyObj('ionicScrollDelegate', ['func1', 'func2']
            controller = $controller('timeInOutController', {
                $scope: scope,
                $filter: filter,
                $ionicScrollDelegate: ionicScrollDelegate
            });
        }));
        describe('#date setting', function(){
            ...
        });
    });
})();

您可以通过jasmine的文档

找到更多关于间谍的信息

您需要为控制器正在使用的所有依赖项创建mock对象。

以这个控制器为例:

angular.module('app.module', [])
    .controller('Ctrl', function($scope, $ionicLoading) {
        $ionicLoading.show();
    });

这里你使用的是$ionicLoading服务,所以如果你想测试这个控制器,你必须模拟那个对象,指定你在控制器中使用的方法

describe('Test', function() {
     // Mocks
     var $scope, ionicLoadingMock;
     var ctrl;
     beforeEach(module('app.module'));
     beforeEach(function() {
         // Create $ionicLoading mock with `show` method
         ionicLoadingMock = jasmine.createSpyObj('ionicLoading', ['show']);
         inject(function($rootScope, $controller) {
             $scope = $rootScope.$new();
             ctrl = $controller('Ctrl', {
                 $scope: $scope,
                 $ionicLoading: ionicLoadingMock
             });
         });
     });
     // Your test goes here
     it('should init controller for testing', function() {
         expect(true).toBe(true);
     });
});