【问题标题】:How to mock $scope.variables in jasmine如何在茉莉花中模拟 $scope.variables
【发布时间】:2015-06-02 01:35:49
【问题描述】:

我有以下测试用例 CompanyCtrlSpec.js

describe('ViewCompanyCtrl', function () {
    var $rootScope, scope, $controller , $q ;

   beforeEach(angular.mock.module('MyApp'));

   beforeEach(inject(function ($rootScope, $controller ) {
        scope = $rootScope.$new();
        createController = function() {
            return $controller('ViewCompanyCtrl', {
            $scope: scope,
            company : {}    
            }); 
        };
    }));

    it('the company type should be equal to an object', function () {
        var controller = new createController();
        //some assertion
    });
});

以下是 ViewCompanyCtrl.js 文件

angular.module('MyApp').controller('ViewCompanyCtrl',
    function ($scope, companyService, $state, meetingService, company, attachmentService) {
        'use strict';

        $scope.company = company;

        $scope.companyInfo = {};
        $scope.companyInfo['AName'] = [$scope.company.Address.Street, $scope.company.Address.ZipCode + ' ' + $scope.company.Address.City].join(', ');
       //more code


    });

以下是 company 正在解析的 app.routes.js 文件

.state('company', {
            abstract: true,
            url: '/company/:companyId',
            resolve: {
                company: function($q, $stateParams, companyService){
                    var deferred = $q.defer();

                    companyService
                        .getCompany($stateParams.companyId)
                        .error(function(data, status, headers){
                            //more code
                        })
                        .success(function(data){
                            deferred.resolve(data);
                        });

                    return deferred.promise;
                }
            },

我的问题是我收到以下错误

        TypeError: $scope.company.Address is undefined in C:/Users/MyApp/WebApiRole/app/compan
y/ViewCompanyCtrl.js (line 8)
        @C:/Users/MyApp/WebApiRole/app/company/ViewCompanyCtrl.js:8:42

我猜这是因为我没有在我的测试用例中模拟 scope.company.Address。我不知道该怎么做。如果有人可以帮助我解决这个问题,或者有任何方法可以做到这一点,请不胜感激?

【问题讨论】:

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


    【解决方案1】:

    在我看来 $scope.company 与注入到控制器中的 company 相同。因此,您只需在要注入模拟的company 上设置Address,如下所示:

    beforeEach(inject(function ($rootScope, $controller ) {
        scope = $rootScope.$new();
        createController = function() {
            return $controller('ViewCompanyCtrl', {
                $scope: scope,
                company : {
                    Address: {/* address data goes here */}
                }
            }); 
        };
    }));
    

    如果您希望每次测试的公司数据不同,只需将其传递到您的 createController() 函数中:

    beforeEach(inject(function ($rootScope, $controller ) {
        scope = $rootScope.$new();
        createController = function(company) {
            return $controller('ViewCompanyCtrl', {
                $scope: scope,
                company : company
            }); 
        };
    }));
    
    it('the company type should be equal to an object', function () {
        var company = {Address: {/* address data goes here */}};
        var controller = new createController(company);
        //some assertion
    });
    

    【讨论】:

    • 谢谢!!我有点知道这个想法,但不知道怎么做,因为我是茉莉花的新手。 +1 解释:)
    【解决方案2】:

    尝试将控制器添加到路由的定义中。控制器不像其他服务那样是单例的。它通常与状态或视图相关联。

    .state('company', {
            abstract: true,
            url: '/company/:companyId',
            controller: 'ViewCompanyCtrl'
            resolve: {
                company: function($q, $stateParams, companyService){
                    var deferred = $q.defer();
    
                    companyService
                        .getCompany($stateParams.companyId)
                        .error(function(data, status, headers){
                            //more code
                        })
                        .success(function(data){
                            deferred.resolve(data);
                        });
    
                    return deferred.promise;
                }
            },
    

    更好的是我会使用controller As 约定而不是在控制器中使用范围。然后您的控制器将成为范围。 除此之外,我强烈建议您查看John Papa's coding standardTodd Motto's。两者都很好,建议使用该约定。

    【讨论】:

      猜你喜欢
      • 2021-12-14
      • 1970-01-01
      • 1970-01-01
      • 2015-08-11
      • 1970-01-01
      • 1970-01-01
      • 2016-11-01
      • 1970-01-01
      • 2015-08-25
      相关资源
      最近更新 更多