How to mock $scope.variables in jasmine

12,817

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

Solution 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.

Share:
12,817
Malik
Author by

Malik

Updated on June 04, 2022

Comments

  • Malik
    Malik almost 2 years

    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 ?

  • Malik
    Malik almost 9 years
    Thank you !! i kinda knew the idea , but didn't know how to do it since i am new to jasmine . +1 for the explanation too :)