Generating a jasmine spy on a connected promise

I am currently trying to test a service that utilizes Restangular, but I am facing difficulties in creating the correct spy on chained promises.

var services = angular.module('services.dashboards', ['models.dashboards', 'models.metrics', 'LocalStorageModule', 'app.filters']);

services.factory('DashboardsService', ['Restangular', '$q', 'Metrics', 'Dashboards', 'localStorageService', '$filter', 'filterByGradedFilter', function (Restangular, $q, Metrics, Dashboards, localStorageService, $filter, filterByGradedFilter) {
    var factory = {};

    factory.getData = function () {
        var defer = $q.defer();
        var data = localStorageService.get('data');
        if (!data) {
            Dashboards.post()
                .then(function (result) {
                    return Restangular.oneUrl('newDash', result.data).get();
                })
                .then(function (result) {
                    data = result.data;
                    localStorageService.set('data', data);
                    defer.resolve(data);
                });
        } else {
            defer.resolve(data);
        }
        return defer.promise;
    }

    return factory;

}]);

The specific chained promise that I am attempting to test is:

            Dashboards.post()
                .then(function (result) {
                    return Restangular.oneUrl('newDash', result.data).get();
                })
                .then(function (result) {
                    data = result.data;
                    localStorageService.set('data', data);
                    defer.resolve(data);
                });

While the test is executing, I am encountering an error:

Error: get() method does not exist
:

describe('Dashboards Service', function () {

    // Holds the service under test
    var service;
    // Dependencies
    var dashboards;
    var restangular;
    var q;
    var rootScope;

    beforeEach(module('services.dashboards'));

    // We inject the service
    beforeEach(inject(function (_DashboardsService_, _Dashboards_, _Restangular_, _$q_, _$rootScope_) {
        service = _DashboardsService_;
        dashboards = _Dashboards_;
        restangular = _Restangular_;
        q = _$q_;
        rootScope = _$rootScope_
    }));

    describe('#getData', function ($rootScope) {
        it('should get a dashboard', function () {
            spyOn(dashboards, 'post').and.returnValue(q.when({}));
            // Tried that but it's not working
            spyOn(restangular, 'oneUrl').and.callFake(function() {
                return this;
                // Also tried return restangular;
            });
            spyOn(restangular, 'get').and.returnValue(q.when({}));
            service.getData().then(function (result) {
                expect(result).toEqual({});
            });

            expect(dashboards.post).toHaveBeenCalled();
            expect(restangular.oneUrl).toHaveBeenCalledWith('newDash');
            expect(restangular.oneUrl.get).toHaveBeenCalled();
            rootScope.$apply();

        })
    })
})

Answer №1

Could you please attempt this?

 spyOn(restangular, 'oneUrl').and.callFake(function() {
               return {
                    get:function() {return q.when({});}
               }
            });

The objective is to create an object that contains a get method which either returns a promise or data.

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

What distinguishes setting a $watch on a string variable from setting a $watch on an object's key in AngularJS?

When using angularJs, I am curious about the distinction between setting $watch on a string variable versus setting $watch on an Object's key. Let me explain with a detailed scenario: $scope.activeMenu = {'id' : '...', 'name ...

Navigating Angular's Resolve Scope Challenges

As a junior developer, I've been diving into Angular.js and exploring the resolve feature of the route provider to preload my Project data from a service before the page loads. Previously, I was fetching the data directly inside the controller. Howeve ...

What is preventing me from injecting a directive into my test cases?

While I have been successful in injecting various things in the beforeEach(inject(beforeEach(inject(function(_$controller_,_mycustomService_,_$log_) in Jasmine, there is one challenge I'm facing when trying to inject a directive. Despite being able ...

Bidirectional communication within a checkbox collection using AngularJS

Here, I am retrieving a list of objects to create a list of checkboxes based on the value of the IsActive column. The checkbox is either checked or unchecked depending on this boolean value. <div class="col-xs-12"> <div class="col-xs-12" ng-r ...

No data returned from AngularJS $q.all

I desperately need assistance with the following problem. I am querying Firebase to retrieve a list of tasks sorted by priority (task date), then iterating through the results. For each task, I am fetching its related job from another branch in Firebase, a ...

Protractor - selecting a hyperlink from a list

Imagine you have a todo application with tasks listed as follows: Walk the dog, Eat lunch, Go shopping. Each task has an associated 'complete' link. If you are using Protractor, how can you click on the 'complete' link for the second t ...

Checking for the existence of inner directives after they have been rendered in AngularJS

While working on a view, I am using myDirective in the following manner: <div my-directive></div> The myDirective includes a template: <div> <div my-inner-directive></div> </div> My query is: How can I determine ...

Incorporate stateProvider views across all modules for seamless navigation between different

Is there a way to use a stateprovider view template across all modules seamlessly? In my index.html file, I have the following setup: <div ui-view="nav"></div> <div ui-view></div> <div ui-view="footer"></div> My confi ...

Error: AngularJS: Invalid Argument Error. The argument 'ClientCtrl' is not defined as a function, it is currently undefined

As a newcomer to AngularJS, I am facing an issue while trying to add a controller to my website. Strangely, the other two controllers are functioning perfectly fine, but this particular one is not being recognized. Here is my app.js file: var app = angul ...

The AngularJS function invoked itself within the structure

When working with my form, I encountered a problem involving custom input directives and text fields. In addition to these elements, there are buttons: one for adding a new input to the form which is linked to the function $scope.AddNewItem() in the contro ...

Exploring the power of directives in AngularJS for dynamically manipulating the

Using angular directives, I am attempting to dynamically replace a portion of HTML within a portlet on a webpage. The portlet contains two embedded sections. The top section includes a heading obtained from a separate backend service. <div class="head ...

Is $timeout considered a questionable hack in Angular.js development practices?

Here's a question for you: I recently encountered a situation where I needed to edit the DOM on a Leaflet Map in order to manipulate the appearance of the legend. To workaround an issue where the map wasn't generating fast enough to access the n ...

Angular Timer offers a single button that can handle starting, stopping, and resuming all with just

Attempting to create a progress bar with integrated Start, Stop, and Resume buttons using the "Angular Timer" directives found here (refer to the progress bar example towards the bottom). The current examples on their site consist of separate Start and Sto ...

What is the best way to display the value of a new object's property in Angular?

I am currently developing a list application that allows users to create new lists by entering a name and clicking a button. Once the list is created, users can add and remove items from the list. However, I have encountered an issue where the name of the ...

Tips on saving checklist values as an array within an object using AngularJS

I need help with storing selected checklist items as an array in a separate object. I want to only store the names of the checklist items, but I am struggling to figure out how to achieve this. Below is the HTML code: <div ng-app="editorApp" ng-contro ...

Accessing parent directives for forms - custom form names and dynamic validation

Introduction My current task involves validating dynamically created forms within a directive. These forms are all managed and submitted separately. When the form is submitted, I need to display validation errors for each individual form without any issu ...

Issue with combining md-grid-tile and md-button in Angular Material not functioning as expected

I've been trying to make a md-grid-list with md-grid-tiles into clickable links by wrapping them in an anchor tag or an md-button, but so far I haven't had any success. The element seems to disappear when I try this method. If anyone has any sug ...

Unable to alter a global variable while iterating through an angular.forEach loop

I've encountered a challenge while attempting to modify a global variable within an Angular.forEach loop. Although I can successfully update the variable within the loop, I'm struggling to maintain those changes when accessing the variable outsi ...

Updating a model in Angular JS after sending a JSON GET request: A step-by-step guide

Having issues with my simple page that displays records based on the selected year. The sidebar selection is not highlighting properly. The initial data loads fine when I first visit the page. However, when I try to change the year and click "Go", the mai ...

Error with Cross-Origin Resource Sharing (CORS) on my website

During the development of a website, I disabled web security in order to bypass CORS using the command chrome.exe --disable-web-security --user-data-dir=/path/to/foo However, after successfully completing the website and uploading it to my domain, I enco ...