使用karma angularjs进行单元测试中的注射问题

时间:2015-09-01 19:24:59

标签: javascript angularjs unit-testing jasmine karma-jasmine

我需要测试一个带有大量注射(服务,工厂,值)的控制器,现在我有一个值有问题......

我有以下情况:

这是我的控制器。

(function () {
'use strict';
angular
    .module('otpConfigureDatasets')
    .controller('otpConfigureDatasetsController', otpConfigureDatasetsController);

otpConfigureDatasetsController.$inject = ['$location', '$state', 'otpWebMapApp', 'otpWMDeltaTracker', 'otpWMStateCache', '$scope', '$timeout', 'otpConfigureDatasetService', 'otpAllDatasetsService', 'otpReviewListDatasetsService','otpConfigureDatasetSelectedTab'];

function otpConfigureDatasetsController($location, $state, otpWebMapApp, otpWMDeltaTracker, otpWMStateCache, $scope, $timeout, otpConfigureDatasetService, otpAllDatasetsService, otpReviewListDatasetsService, otpConfigureDatasetSelectedTab) {

    var vm = this;
    ...

    vm.tabs = [{
        title: 'MY REVIEW LIST',
        selectedAmt: vm.reviewData,
        contentTemplate: './app/features/configureDatasets/reviewListDatasets.html',
        active: otpConfigureDatasetSelectedTab.tab == 'MyReviewList'
    }, {
        title: 'ALL DATASETS',
        selectedAmt: vm.allData,
        contentTemplate: './app/features/configureDatasets/allDatasets.html',
        active: otpConfigureDatasetSelectedTab.tab == 'AllDatasets'
    }];

    ...
}
})();

我的Spec.js

'use strict';

describe('Test', function () {

var MainCtrl, scope, _otpWebMapApp_, _otpWMDeltaTracker_, _otpWMStateCache_, _otpConfigureDatasetService_,
    _otpAllDatasetsService_, _otpReviewListDatasetsService_, _otpConfigureDatasetSelectedTab_;


beforeEach(function () {
    module('otpConfigureDatasets');
});


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

    scope = $rootScope.$new();
    MainCtrl = $controller('otpConfigureDatasetsController', {
        $scope: scope, otpWebMapApp: _otpWebMapApp_, otpWMDeltaTracker: _otpWMDeltaTracker_, otpWMStateCache: _otpWMStateCache_,
        otpConfigureDatasetService: _otpConfigureDatasetService_, otpAllDatasetsService: _otpAllDatasetsService_,
        otpReviewListDatasetsService: _otpReviewListDatasetsService_, otpConfigureDatasetSelectedTab: _otpConfigureDatasetSelectedTab_
    });    

}));



it('Should be true', function () {
    expect(true).toBe(true);
});


});

但是当我尝试运行测试用例时,它不起作用并显示以下错误:

INFO [karma]: Karma v0.12.37 server started at http://localhost:9876/
INFO [launcher]: Starting browser PhantomJS
INFO [PhantomJS 1.9.8 (Windows 8 0.0.0)]: Connected on socket NHknSeC3p_h_lf12SK Gh with id 27552356
PhantomJS 1.9.8 (Windows 8 0.0.0) Test Should be true FAILED
    TypeError: 'undefined' is not an object (evaluating 'otpConfigureDatasetSelectedTab.tab')
        at otpConfigureDatasetsController (D:/workspace/.....

我已经拥有karma.config.js中的所有必需文件....

如果我在控制器中注释这两行。

//active: otpConfigureDatasetSelectedTab.tab == 'MyReviewList'

//active: otpConfigureDatasetSelectedTab.tab == 'AllDatasets'

单元测试工作正常。

我的Spec定义有什么问题???

1 个答案:

答案 0 :(得分:0)

您没有保存您尝试模拟的对象。你基本上只有

_otpConfigureDatasetService_ = undefined,
_otpReviewListDatasetsService_ = undefined

因此,控制器不是失败的,而是单元测试。您正在注入undefined代替两个对象。我不确定你想要做什么,但你需要定义一些模拟对象,如_otpConfigureDatasetService_ = {tab: 'something'}或获取真实服务并调整它们

beforeEach(inject(function ($controller, $rootScope, otpConfigureDatasetService, otpReviewListDatasetsService) {

    //
    _otpConfigureDatasetService_ = otpConfigureDatasetService;
    _otpReviewListDatasetsService_ = otpReviewListDatasetsService;
    //
    scope = $rootScope.$new();
    MainCtrl = $controller('otpConfigureDatasetsController', {
        $scope: scope, otpWebMapApp: _otpWebMapApp_, otpWMDeltaTracker: _otpWMDeltaTracker_, otpWMStateCache: _otpWMStateCache_,
        otpConfigureDatasetService: _otpConfigureDatasetService_, otpAllDatasetsService: _otpAllDatasetsService_,
        otpReviewListDatasetsService: _otpReviewListDatasetsService_, otpConfigureDatasetSelectedTab: _otpConfigureDatasetSelectedTab_
    });    

}));

BTW的惯例是在inject函数中定义_object_然后保存它。如果你注入了它们的调用方式,那么你就不需要为你的局部变量使用_object_形式了。

我也更喜欢使用$ injector

beforeEach( inject(function($injector) {
    exampleService = $injector.get('exampleService');
}));