How to mock $scope.variables in jasmine

本秂侑毒 提交于 2019-12-12 13:01:07

问题


I have the following test case 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
    });
});

Following is ViewCompanyCtrl.js file

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


    });

Following is the app.routes.js file where company is getting resolved

.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;
                }
            },

My problem is that i get the following error

        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

I am guessing that this happens because i didn't mock the scope.company.Address in my test case . I am not sure how to do that . Appreciate it if Any one can help me with this , or any method to do this ?


回答1:


It looks to me like the $scope.company is the same as the company that is injected into your controller. So you need only to set an Address on the company that you are injecting into your mock, like so:

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

If you want the company data to be different for each test, simply pass it into your createController() function:

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
});



回答2:


Try to add the controller to the definition of your route. A controller is not a singleton like the other service. It is usually tied to a state or a view.

.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;
            }
        },

Even better I would use the controller As convention instead of using scope in your controller. Then your controller will be come the scope. Aside for that I would highly recommend having a look at John Papa's coding standard or Todd Motto's. Both are good and will recommend to use that convention.



来源:https://stackoverflow.com/questions/30570617/how-to-mock-scope-variables-in-jasmine

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!