Exploring ways to efficiently test the nested promises in an Angular service function

Here is a snippet of what my service implementation looks like:


TestService.initializeDefaults = function() {
    var qPromise = $q.defer();
    $q.all({
        localResource: localResource.fetch(),
        item: itemResource.fetch()
    }).then(function(directories) {

        // perform operations with directories
        $q.all({
            thing1: anotherThingFetch.fetch(),
            thing2: someThingFetch.fetch(),
            thing3: thingFetch.fetch()
        }).then(function(funData) {
            // perform operations with the data

            preventiveServicesService.fetch().then(function() {

                // more operations
            });

        });
    }.bind(this));
    return qPromise;
};

I am working on using Karma to test whether all the functions within the initializeDefaults method have been executed successfully. This means ensuring that all fetch requests have completed. Here's a snippet of my current test code:


it("should initialize defaults (Scenario 1)", function() {

    service.initializeDefaults();

    rootScope.$apply();

    expect(localResourceMock.fetch).toHaveBeenCalledWith();
    expect(itemResourceMock.fetch).toHaveBeenCalledWith();

Answer №1

There are a couple of approaches you can take with this.

1) Utilize $httpBackend: Set up something like $httpBackend.expectGET('url1').respond(200, {}) for each $http call you need to make. Then use $httpBackend.flush() to trigger all nested promises as well. Drawback: This method will execute all the logic in the invoked methods.

2) Harness Jasmine spies: Create something along these lines:

let deferred = $q.defer();
deferred.resolve(/*expected data from promise*/); 
spyOn(localResourceMock, 'fetch').and.returnValue(deferred.promise);
spyOn(itemResource, 'fetch').and.returnValue(deferred.promise);

spyOn(anotherThingFetch, 'fetch').and.returnValue(deferred.promise);
/*Repeat for all invoked methods*/

// Call the method
service.initializeDefaults();

// Activate digest cycle
rootScope.$digest();

/*Check that all spies were called*/
expect(anotherThingFetch.fetch).toHaveBeenCalledWith(); // should pass now

Either approach will function. Your move. Cheers.

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

Having trouble getting your jQuery code to work in your HTML document after converting it to

Recently, I've been working with HTML5, CSS, and vanilla JavaScript. I wanted to convert this jQuery code and make some changes to it. However, I seem to be encountering an issue after implementing the new code. The original code had a small triangu ...

Creating Seamless, Unified Shape-to-Shape (Containers) Transition with CSS and JavaScript - A Step-by-Step Guide

I am experimenting with creating a unique effect where two rectangular shapes, each containing text and with rounded ends, move towards each other, merge to form a single rounded rectangle as the page is scrolled down, and then separate back when scrolling ...

Cannot get the before-leave transition JavaScript hook to function properly in Vue.js

I am facing an issue with my variable, transitionName, in the beforeLeaveHook function. Despite attempting to change it to 'left', the value remains stuck at 'right'. Any assistance on resolving this matter would be greatly appreciated. ...

How can you set a $_GET variable without having to reload the page?

I have a table on my website that displays values for each row, and here's an example code snippet: //JAVASCRIPT <tr onclick="window.history.replaceState(null, null, 'myPage.php?ID=2');"> The URL changes with this code, but it doesn& ...

What is the best way to change a date from the format DD/MM/YYYY to YYYY-MM-DD

Is there a way to use regular expressions (regex) to convert a date string from DD/MM/YYYY format to YYYY-MM-DD format? ...

Encountering problem with selecting values in Select2 with ajax

I have implemented the Select2 plugin in my code as shown below: JavaScript function initAssignmentsAjax() { $("#assignments").empty(); $( "#assignments" ).select2( { placeholder: "Select an assignment", allowCle ...

I encountered a TS error warning about a possible null value, despite already confirming that the value

In line 5 of the script, TypeScript raises an issue regarding the possibility of gameInstanceContext.gameInstance being null. Interestingly, this concern is not present in line 3. Given that I have verified its existence on line 1, it is perplexing as to w ...

Utilizing the 'PUT' update technique within $resource

Hey there, I'm pretty new to Angular and looking for some guidance on how to implement a PUT update using angular $resource. I've been able to figure it out for all 'jobs' and one 'job', but I could use some assistance with in ...

Updating Object Properties in Vue.js 2.0 using Methods

I am facing an issue where I have an object with blank properties in my component's data. I want to update these properties using a method that is triggered by a click event on one of the listed elements. However, when I check the click event in the c ...

In JavaScript, alert a message once all images have been clicked

I'm encountering a small issue with my javascript code. I am developing a game for a school project where the objective is to click (remove) fish using a fishing rod. However, the game does not have an end condition set up, so players cannot win. Belo ...

The try/catch block proves ineffective at handling a socket connection exception

I am attempting to test connection to a non-existent socket. In this scenario, an exception is thrown and I anticipate it being caught in the try/catch block below. The function createConnection is imported from the net package. try { createConnection( ...

Rotating through elements in timed intervals

After exploring various examples of how to show/hide divs with a JavaScript timeout, I am still unable to resolve my specific issue. I currently have six divs that I want to cycle through sequentially every 10 seconds, starting with div #one. Although my ...

Looking to create a drag-and-drop form designer within a web browser - Is AngularJS the optimal framework for this task?

I am in need of developing a web form designer that can be used directly in a browser. Similar to tools like Zoho Creator, proto.io, protoshare, gomockingbird, and lucidcharts. The design will include a tool palette, canvas, and properties box for easy con ...

Issue regarding angularjs type definitions

I am facing an issue with installing typings for Angular and I need some guidance on how to resolve the error. Any suggestions or assistance would be greatly appreciated! Below is the error message that I encountered: ERROR in C:\Users\test&b ...

Having difficulty with printing a particular div

I need help with printing a specific div containing checkboxes using jQuery. The checkboxes are initially checked based on data from a database, but when I try to print the div, the checkboxes remain unchecked in the print view. Below is the code snippet ...

I'm struggling to solve a straightforward jQuery sliding issue

I am struggling to make text slide from right to left on my website. I want the text to appear only when the page loads or refreshes, and then slide off when a link is clicked, revealing new text. Can anyone help me figure this out? http://jsfiddle.net/XA ...

The reason why JavaScript condenses two or more spaces into just one space

After encountering a problem with my HTML/JS/Angular script, I created a simple demo to illustrate the issue. Although I have found a solution, I still wanted to seek advice from experts. <body ng-app> <div ng-controller='abc'> ...

Freeze your browser with an Ajax request to a specific URL

There is a function in my view that transfers a value from a text box to a table on the page. This function updates the URL and calls another function called update_verified_phone(). The update_verified_phone() function uses a model called user_info_model( ...

How can I use Node.js Express to upload files with Multer?

I am facing an issue while trying to upload a file image using multer in express. The file gets successfully uploaded to the directory, but the name of the file is not being saved in the database. I am utilizing mongodb with express and currently, the file ...

Is it possible to trigger a reflow prior to initiating a lengthy JavaScript operation?

Ready to face the criticism, I understand that this question has been asked many times before, and I am aware that there are likely more efficient ways to achieve what I'm trying to do... In a JavaScript function, I have a process that can take up to ...