【问题标题】:Injecting $stateParams for angular unit testing testing with karma使用 karma 注入 $stateParams 进行角度单元测试
【发布时间】:2016-04-07 07:01:08
【问题描述】:

让我们从控制器代码开始:

angular
.module('hc.hotelContent')
.controller('NameLocationController', nameLocationCtrlFn); //Todo change hotelDataService
nameLocationCtrlFn.$inject = ['$stateParams', 'hotelDataService'];

  function nameLocationCtrlFn($stateParams, hotelDataService) {
       var vm = this,
       hotelId = $stateParams.hotelId;
       vm.Keys = {
        Name: 'Name',
        Street: 'Street',
        City: 'City',
        State: 'State',
        Zip: 'Zip',
        Country: 'Country'
    }
}

我确实有更多代码,但它的逻辑无关紧要,当我不将 $stateParmas 注入控制器时,我的测试工作正常。
所以这里是测试文件:

    describe('nameLocation component Controller', function () {
    var $controller,
            hotelDataServiceMock,
           stateParams,
            hotelId = "4611";
Keys = {
        Name: 'Name',
        Street: 'Street',
        City: 'City',
        State: 'State',
        Zip: 'Zip',
        Country: 'Country'
    }//@
    beforeEach(module('hc.hotelContent'));
        beforeEach(module('hc.app.core'));
        beforeEach(inject(injectFn));
       function injectFn(_$controller_, $stateParams, _hotelDataService_) {
            $controller = _$controller_;
            stateParams = $stateParams;

            hotelDataServiceMock = _hotelDataService_;
        } //controller injection fn

        function initCtrl() {
            controller = $controller('NameLocationController', {
                $stateParams: stateParams,
                hotelDataService: hotelDataServiceMock
            });
        }
describe('inserting a new hotel', function () {
        it('should populate Keys object', function () {
            var controller = initCtrl();
            expect(controller.Keys).toEqual(Keys);
        });
   }
}

我收到未知提供程序错误。这与我的控制器无关,我在控制器中所做的所有事情都是将变量设置为 $stateParams 变量。 我如何使用这种注射剂? 我的 karma.conf 文件被配置为以这个特定的顺序加载 jquery、angular、ui-router、mocks,然后是所有的 js 和 html

编辑:我之前确实看过this post 这篇文章,但我在我的主应用程序模块中使用 ui-router,所以我添加了 beforeEach(module('hc.app'));到代码,但仍然没有

【问题讨论】:

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


    【解决方案1】:

    问题是injectFn 中的参数名称$stateParams 与您引用的变量(_$stateParams_)不匹配吗? _$stateParams_injectFn 中未定义。

    如果这不起作用,您是否也将 ui-router 注入到您的模块中,并且该模块是否已加载到您的测试中? this question也有类似的问题。

    如果您只想测试控制器是否使用$stateParams.hotelId,您还可以使用以下内容模拟$stateParams

    function injectFn(_$controller_, _hotelDataService_, $provide) {
        $controller = _$controller_;
        hotelDataServiceMock = _hotelDataService_;
        $provide.value('$stateParams', {
            hotelId: 'someId',
        });
    }
    
    function initCtrl() {
        return $controller('NameLocationController', {
             hotelDataService: hotelDataServiceMock,
        });
    }
    

    【讨论】:

    • 不,这只是我改变的一种类型。 ui 路由器被注入到另一个模块中
    • angular.module('hc.app', ['hc.app.core', 'hc.app.shared', 'hc.hotelContent', 'hc.templateHtml', 'ngMdIcons' , 'ngMaterial', 'ui.router' ]);
    • 已编辑 - 阐明您必须加载一个将 ui-router 作为依赖项的模块。 (beforeEach(module('hc.app'));)。我还添加了一种模拟 $stateParams 的方法。
    • 做到了,仍然没有,我想使用 stateParams 并且不提供它,因为该值是由路由器传递的,稍后将包含更多参数
    【解决方案2】:

    在指令中测试 $stateParams 时遇到类似问题:

    尝试注入$state

    然后你可以使用: $state.go('namedurl', {your_params_here}) $rootScope.$digest() 或 $apply 在您的控制器中

    这将更新$stateParams。如果您尝试将$stateParams 作为模拟注入提供程序,它们只会被 $state 服务覆盖。

    【讨论】:

    • 我喜欢这个解决方案的简单性,以及您只需了解很少的角度管道即可使其工作。这确实有助于让您的测试保持简单。
    猜你喜欢
    • 1970-01-01
    • 2019-05-01
    • 2020-05-30
    • 2016-12-21
    • 2020-12-07
    • 2015-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多