Using sinon to stub a scope method called during the initialization of an angular controller

When I create a new controller, it automatically triggers a method linked to the $scope:

angular.module('example', []).controller('exampleCtrl', function($scope) {
    $scope.method = function () { ... };

    $scope.method();
});

I am trying to verify that this method is indeed called during the controller's creation. To do this, I am using jasmine for testing and sinon.js for mocking.

describe('tests', function() {
    var $scope, $controller;

    beforeEach(inject(function($rootScope, _$controller_) {
        $scope = $rootScope.$new();
        $controller = _$controller_;
    });

    describe('During construction', function() {
        it('should call "method"', function() {
            $controller('exampleCtrl', { $scope: $scope });

            var methodStub = sinon.stub($scope, 'method');

            expect(methodStub.called).toBe(true);
        });
    });
});

However, my test fails because the $scope.method() is invoked immediately after $controller(), which doesn't give me time to stub it out. I tried to stub it out before creating the controller:

it('should call "method"', function() {
    var methodStub = sinon.stub($scope, 'method');

    $controller('exampleCtrl', { $scope: $scope });

    expect(methodStub.called).toBe(true);
});

But then I encountered an error from sinon:

TypeError: Cannot read property 'restore' of undefined
. This happened because $scope.method was not yet defined since the constructor had not been called.

I also experimented with directly stubbing the method on the $scope, like this $scope.method = sinon.stub(), but unfortunately, it gets overridden during the controller's construction.

Is there a way to successfully stub a method called during the controller's construction?

Answer №1

Attempting to use stub may not produce the desired outcome as controllers tend to override it.

The importance lies in maintaining clean and organized code.

Primarily, complex logic should be avoided in the controller. Most often, testing involves mocking dependencies to ensure proper function calls.

Additionally, it is recommended to utilize the "controller as" notation. This allows the controller to act as a traditional JS class where methods defined in the prototype can be easily mocked or stubbed.

In essence, if there is a need for such unusual requirements, it may indicate that the controller is becoming too complex.

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

Placing a function within an array raises the question: why is the array's value represented as an integer?

There's something puzzling happening in my code. I've placed a setTimeout function inside an array, but when I check the contents of the array using console.log(arr), it only shows an integer value. How is this possible? See the code snippet belo ...

javascript the unseen element becomes visible upon page loading

my website has the following HTML snippet: function getURLParameters() { var parameters = {}; var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) { parameters[key] = value; }); return param ...

What are some ways to display multiple divs within a single popup window?

I am attempting to create the following layout: https://i.sstatic.net/OzE98.png Here is what I have been able to achieve: https://i.sstatic.net/7GxdP.png In the second picture, the divs are shown separately. My goal is to display the incoming data in a ...

Setting up and customizing Express with Angular

Currently working on a straightforward Angular/Express todo-list app, I encountered some difficulties. As the project is still in progress, after running the code on localhost:3000, I noticed that {{ thing }} was displayed literally on the webpage. The di ...

Creating a Modal Popup with Bootstrap 5 in Asp.net using C#

Despite trying everything, I was unable to achieve success. <script type="text/javascript"> function openModal() { var myModal = new bootstrap.Modal(document.getElementById('KullaniciAramaSonuc'), {}); myModal.show(); ...

Troubleshooting a JavaScript function's ineffectiveness when triggered by clicking an

What is causing the function to not work properly when I click on the "Rate me" button? function increaseValue(){ var rate = parseInt($("#rateme").value, 10); rate = isNaN(rate) ? 0 : rate; rate++; $("#rateme").value = rate; } <scr ...

Implementing validation for multiple email addresses in JavaScript: A step-by-step guide

Currently, I am utilizing Javascript to perform validation on my webpage. Specifically, I have successfully implemented email validation according to standard email format rules. However, I am now seeking assistance in enhancing the validation to allow for ...

updating the content of a webpage using innerHTML on Squarespace platform

Could anyone help me with changing the status from "sold out" to "coming soon" on this specific page? Below is the code I have tried, but unfortunately, it is not working as expected. window.onload = function() { document.getElementsByClassName("produ ...

configuring conditions for protractor end-to-end tests

We have incorporated Protractor for testing our front-end Angular application currently under development. While using browser.get() to define the environment we intend to test (localhost:9000, staging, UAT), I am exploring options to parametrize this so ...

Determine if a string begins with a single letter, then has one or more digits, followed by any other characters

How can I adjust the pattern below to return true in cases like these: m1, m1a, M100bc, s45, S396xyz and return false in cases like these: '', m, 1, 1a, mm, Mx, mm1, SS1b The current pattern is: /^m\S\.*/i.test(text) Currently, it ...

Xcode 4 encountering linker error in unit test situation

Everything was running smoothly with my application and unit tests until I added some code for CGAffineTransform. Now, the unit tests are failing while the application still runs fine. This issue is consistent across both simulator and device. The error ...

AngularJS and Karma: Revoking ng-dirty status using setPristine

I'm currently facing an issue in one of my unit tests where I am testing the removal of ng-dirty when using setPristine on an input element. Even after calling setPristine, the ng-dirty is not being removed. My suspicion is that I may be incorrectly ...

I am experiencing an issue where my React application is not loading the fonts when utilizing `type: 'asset/resource'` to load fonts within a CSS file. Can anyone provide guidance on

I'm encountering an issue with my webpack setup where fonts are not being loaded when using type: 'asset/resource'. Actually, there are several problems arising from the use of asset/resource, but let's focus on this particular issue fo ...

I am looking to create an extension that can automatically paste text from a variety of lists, but unfortunately, I am struggling to get it up and running correctly

I'm having trouble pasting text into text boxes or documents. I've tried various methods, but nothing seems to work. Am I missing something? Is there a solution or could I get some assistance? manifest.json { "manifest_version": 3, ...

What methods are available for managing model fields within a for loop in Django?

As a newcomer to Django, I am embarking on the journey of creating a Quiz web application that presents one question at a time. Upon selecting an answer using radio buttons, the application should promptly display whether the response is correct or incorre ...

What is the best way to convert the date 19990813 from the format YYYY-MM-DD to 13.08.1999 in the format DD-MM-YYYY, using dots as separators?

Struggling to convert the string date 19990813 provided by the backend into the format 13.08.1999 with dots. Unable to do so successfully. Even when using Angular's built-in date format function, always ending up with the incorrect date. Any suggest ...

JavaScript file slicing leads to generating an empty blob

I am currently working on a web-based chunked file uploader. The file is opened using the <input type="file" id="fileSelector" /> element, and the following simplified code snippet is used: $('#fileSelector').on('change', functio ...

Guide to putting a new track at the start of a jPlayer playlist

I am currently working on a website that utilizes the jPlayer playlist feature. I am facing an issue, as I need to implement a function that adds a song to the beginning of the playlist, but the existing add function only appends songs to the end of the pl ...

Utilizing a jQuery variable within an .html() method

Can a Jquery if statement be used to display different content inside a div based on a variable? For example, if the variable is set to "cats", the displayed content might say "I like cats", and if it changes to "dogs", it would read "I like dogs". Is this ...

How can we universally detect and resolve the user's language within a React/Next.js application using an Apollo client HOC?

Currently, I am developing an I18n module utilizing the Next.js framework (v5). The challenge I am facing is determining the user's default language universally in order to display the UI in that language. While it is relatively simple to resolve th ...