Karma glitch - Anticipated undefined to have a definition

Attempting to unit test my controller has presented some challenges. While basic test assertions using the expect API worked fine, I encountered an issue when trying to mock scope methods within a conditional check. An undefined error was thrown as the method was not available under scope, with only the global logout() method accessible.

I attempted to mock the localStorageService using spyOn to no avail. Any insight or solution would greatly help me get started.

Sample Controller:

angular.module('app').controller('sampleCtrl',

        function($scope, $state, $http, $rootScope, localStorageService) {

            if (!(localStorageService.get('isAuthenticated'))) {

                 $state.go('home');

            }
            if (localStorageService.get('isAuthenticated') === true) {

                 //http post calls made here to perform certain operation on page load

                 $scope.someMethod = function(){

                     //do something

                  }

            }

            $scope.logOut = function() {

               localStorageService.set('property', '');

               localStorageService.set('isAuthenticated', false);

               $state.go('home');

          };
 });

Karma:

'use strict';

describe('Controller: sampleCtrl', function() {

    /** to load the controller's module */
    beforeEach(module('app'));

    var sampleCtrl,scope,httpBackend,deferred,rootScope;

    beforeEach(inject(function ($controller,_$rootScope_,$httpBackend,$q) {

        var store = {};
        scope= _$rootScope_.$new(); // creates a new child scope of $rootScope for each test case
        rootScope           = _$rootScope_;
        localStorageService = _localStorageService_;
        httpBackend         = $httpBackend;

        httpBackend.whenGET(/\.html$/).respond(''); 

        spyOn(localStorageService, 'set').and.callFake(function (key,val) {
            store[key]=val;
         });

        spyOn(localStorageService, 'get').and.callFake(function(key) {
            return store[key];
         });

        sampleCtrl = $controller('sampleCtrl',{
            _$rootScope_:rootScope,
             $scope:scope,
             $httpBackend:httpBackend,
            _localStorageService_:localStorageService
            // add mocks here
        });

        localStorageService.set('isAuthenticated',true);

    }));

    /**ensures $httpBackend doesn’t have any outstanding expectations or requests after each test*/
    afterEach(function() {
        httpBackend.verifyNoOutstandingExpectation(); 
        httpBackend.verifyNoOutstandingRequest();     
    }); 


    it('sampleCtrl to be defined:',function(){

        httpBackend.flush(); 
        expect(sampleCtrl).toBeDefined();

    });

    // failing test case - scope.someMethod not available in scope
    it('is to ensure only authenticated user can access the state methods',function(){
            localStorageService.get('isAuthenticated');
            httpBackend.flush();
            expect(scope.someMethod).toBeDefined(); 
    });


});

Answer №1

Successfully resolved the issue. The root cause was that the localStorageService did not initially have the isAuthenticated flag set to true when the controller started. Ensure to set it to true before initiating the controller.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using JavaScript to convert the text within a div into negative HTML code

I am working with this specific div: <div class="signs" id="signs" onclick="toggle()">&#43;</div> It currently displays the positive sign. I have set up a JavaScript function that is triggered when the div is ...

What is the best way to initiate a function upon each page load?

(Apologies in advance for any English mistakes) Hello everyone, I am currently developing a simple Chrome extension to edit certain graphics and text fields on a website (Freshdesk) that cannot be modified directly on the site due to proprietary code. ...

I would like to create a map showing the selected locations by checking them off using checkboxes

How can I draw a road map by selecting locations with checkboxes in form.php? After posting the selected locations to map.php file and assigning them to a $location array, how do I then assign these values to the waypoints array in the javascript calcRoute ...

Determine the quantity of items currently in an active state

I created a function that toggles the active state of list items when clicked: React toggleActive: function(item){ item.active = !item.active; }, JSX <li key={property.id} onClick={() => this.toggleActive(property)}> Is there a way to count ...

How can we adjust the number of items based on the width of the viewport in Vue.js?

Imagine having a template that showcases a specific number of items, like this: <template> <div> <div v-for="item in items.slice(0, 10)" :key="item" /> </div> </template> How can I adjust the numbe ...

Similar to Angular ui-router 1.0.3, what is the equivalent function for reloadOn

After updating to UI-router v1.0.3 from v0.3.2, I noticed that the reloadOnSearch feature has been removed from the stateConfig. I'm having trouble finding the equivalent of reloadOnSearch in v1.0.3. It doesn't seem to be documented anywhere. A ...

Check the status of the audio source URL using JavaScript

I am currently live streaming audio to my player using the Soundcloud API. <audio></aidio> <source src="soundcloud-track-url"></source> Within my code, I have added an onerror eventListener for both the <audio> and <sourc ...

How can I transfer data from two queries to Jade using Node.js (Express.js)?

I have a database with two tables - one for storing user information and another for managing friendship connections: setting up a friend list in mysql My goal is to create a profile page using Jade, specifically profile.jade: - each user in users ...

steps for transferring a shallow copy of an array to a function

How can I adjust this code so that when I press each button, the console.log displays a different slice of the array instead of always showing me the last 20 elements? for (var i = 0; i < array.length; i++) { var b; var NewArr = []; ...

Associating models using a many-to-many relationship in Sequelize unexpectedly restricts the ability to modify attributes in the join table

I am in the process of incorporating a voting feature into my app, allowing users to vote on responses from other users. The backend of my Node app is built using Express and Sequelize. Currently, I am utilizing a SQLite database for testing convenience. ...

Step-by-step guide to initializing a project using React with Typescript and a functional server-side script

I am working on a project that involves a React Typescript app (created using Create React App). In this project, I need to have an executable script that can run alongside the React app. Both the app and the script are intended to only run on local machin ...

Locating the matching value in the <select> element and showcasing it

I'm trying to create a function where selecting an option from one dropdown menu will display the corresponding value in another column. For instance, if someone chooses "3" from the first dropdown, the value displayed in the third column should be "3 ...

The preflight OPTIONS request for an AJAX GET from S3 using CORS fails with a 403 error

I have come across various discussions and issues related to this topic, but unfortunately, I have not been able to find a solution yet. I am attempting to use AJAX GET to retrieve a file from S3. My bucket is configured for CORS: <?xml version="1.0" e ...

Issue with setting HTML content using jQuery's .html() method

I have a simple functionality. When a user clicks on the edit link, it transforms the previous element into an input element for editing, and changes the edit link into a cancel link. If the user decides not to edit, they can click on cancel and everything ...

What is the best way to access a private class variable within the sockent.on function in Angular?

export class AppComponent { title = 'my-app'; constructor(private notifyService : NotificationService) {} ngOnInit() { socket.on("laravel_database_chat:test", function(message){ //I AM ATTEMPTING TO INVOKE THE NOTIF ...

Angular and Three JS collaboration leads to misplacement of canvas rendering

Currently in the process of developing code for a website, I am attempting to integrate Three JS with Angular. After conducting some research, I have found that this combination is feasible and I have successfully merged these two libraries. However, I am ...

Simulated service integrated into the Angular module initialization block

While working in the module.run block, I encountered a situation where I needed to call a method from a service that I had created. To properly test my controller without making actual http requests, I wanted to use a mock service instead of the real one. ...

Conceal or reveal radio buttons according to information in a table

How can I dynamically add and remove values from a table based on radio button selections? My goal is to add the selected value to the table and hide it from the radio button list, and if the value is deleted from the table, I want to show it back in the r ...

Leveraging clusters in Node.js for REST API deployment

Within my node.js application, I have a REST API that contains complex logic with extensive looping, taking over 7 seconds to complete. As the loop count may increase in the future, the processing time is bound to increase as well. To optimize performance ...

Is there a way to add a listener to a variable within my AngularJS controller?

I need to create a listener for my titleChanged variable. However, when I attempted it this way, I encountered the following error: TypeError: this.$watch is not a function var titleChanged = false; function changeTitle() { t ...