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

Using template expressions to access properties that contain spaces

Here is the code structure that I am working with: "name": { "age": [ { "data": { "how old": "23" } }, One of my JSON keys has a space in it. How can I access this pr ...

modify the color of text in a row within a jquery ajax table

Is it possible to change the font color of values in a row based on a condition inside a function? Specifically, if the TotalStudent count exceeds the room capacity, can we add student information to the table with red font color? Below is my attempt using ...

AngularJS not passing date data to web API

Greetings! I am currently working on a web application using AngularJS. I have a date value in AngularJS, for example 13-10-2017. In C#, I have the following field: public DateTime LicenseExpiryDate { get; set; } When I send 13-10-2017 in an AJAX reques ...

Dealing with file upload dialog using Selenium web automation

I am having difficulty managing the 'select files to load' dialog using Selenium WebDriver. Here is the HTML code snippet: <form class="upload"> <button class="btn" data-capture="" type="button">Browse</button> <inpu ...

Is it possible to retrieve calculated data from a child component and pass it to the parent component?

Is there a way to transfer computed data from a child component to a parent component? Currently, I am passing data from the parent to the child first and then I would like to utilize the computed property (data) in the parent component. This is crucial as ...

Decline the input according to the percentage

After experimenting with the script, I discovered that it did not perform as expected (even though it works on Google Webapp's script HTML form). My goal is to invalidate an input if the Downpayment is less than 30% or more than 100% of the Price, in ...

Difficulty encountered while implementing Ajax POST in CodeIgniter

I've been working on a project similar to a ticket system that occasionally requires lengthy answers. When using CKEDITOR in the answer area, the agent's changes are automatically saved to the database using Json GET. However, I encountered an er ...

Deciding whether an array forms a chain of factors

I am curious about the reasons why this code is failing some of the tests provided. It deliberately avoids using any ES6 code. Here is the given prompt: *A factor chain can be defined as an array where each preceding element serves as a factor for the su ...

I don't understand why this error keeps popping up. It seems that there are several `InputBase` components nested within a

Issue: The error message indicates that there are multiple instances of the InputBase component within a FormControl, causing visual inconsistencies. Only one InputBase should be used. I have tried enclosing my forms within the FormControl, but the error ...

Is it possible to implement a while loop in React?

Issue: I am facing a challenge while attempting to generate an array of 4 elements from a list using a while loop, but it seems to result in an infinite loop. const [options, setOptions] = useState([]); const fetchElements = () => { while(options. ...

I would like to learn how to style my React component by adding borders to the table, as well as the tr, th, and td elements

I am trying to apply borders to the tr, th, and td elements within a styled component div that already has a border applied to the table element. Here is the current code I have: The styled component const Skill1 = styled.div` border: 1px solid black; &g ...

`"Unable to execute the 'ng build --env=prod' command"`

I have a JavaScript website that I need to rebuild with some changes I made. In order to build the application, I was instructed to run this command from the source files directory: ng build –env=prod However, when I try to do so, I keep encountering t ...

The function setState() is not performing as expected within the useEffect() hook

After retrieving data from my Mongo database, it's returned as an object within the useEffect hook function, specifically in the response. I then initialize a state called myorders with the intention of setting its value to the data fetched from the A ...

Top recommendation for utilizing $scope variables in Angular applications

Currently, I am working on a new project and I want to ensure that I am correctly utilizing $scope. After watching an informative video on best practices, Miško mentioned that manipulating $scope properties directly may not be the best approach. Typical ...

Skipping the validation of a variable in a return statement with Angular and Javascript

Is there a way to exclude level a.3 from the return in the completion form if a.3 is undefined? scope.isValid = function() { return a.1 && a.2 && a.3; }; ng-disabled="!isValid()" ...

Checkbox switching in an AngularJS Bootstrap table

Our development team is currently working on a table widget within ServiceNow and we are aiming to include the functionality to select or de-select all rows using a checkbox. Here is a glimpse of our current HTML structure: <table class="table table-st ...

One URL serving dual purposes with HTML and JSON responses

Are there any guidelines or best practices for using the same URL to serve both HTML and JSON responses? For instance, in the scenario where I'm creating a blog and have a URL that displays the latest items, such as /latest. I want to use this URL fo ...

Why won't my AngularJS checkbox stay checked?

In my application, I have the following code: <input type="checkbox" ng-checked="vm.eduToEdit.test" /> {{vm.eduToEdit.test}} <input type="checkbox" ng-model="vm.eduToEdit.test"> The value of vm.eduToEdit.test is displaying t ...

Inserting a large number of records in MySQL using a batch insertion method

Currently, I am facing an issue with inserting multiple records into a MySQL table at once. Just so you know, I am using Node.js along with MySQL (you can find more information about it here: https://www.npmjs.com/package/mysql) Here is what I have been ...

Issues with React JS and JavaScript filtering functionality not working correctly

I've been working on implementing a filter feature for a website, using an HTML range slider. However, I've encountered an issue where the values only update correctly when decreasing. For example, if I set the slider to $500, only products that ...