During the Jasmine test, an error was encountered when trying to call a factory function that includes both a local and another function. The error message displayed

I have a factory with two functions and two local methods. I have written a Jasmine test case in which I expect the local method updateDetails and the factory function SavePref.savePref to be called when

SavePref.saveDetails(values, prop);
is invoked, as shown below:

        SavePref.saveDetails(values, prop);
        expect(updateDetails).toHaveBeenCalled();
        expect(SavePref.savePref).toHaveBeenCalled();

However, when I run the test case, I encounter the following error:

Error: Expected a spy, but got Function.

Can someone please suggest a solution for this?

Here is my factory code:

 app.factory('SavePref', function($rootScope, Restangular) {

            updateFiles = function(prop) {
                if (!prop.found) {
                    _.merge(prop.oldFiles, prop.newFiles);
                }
            };

            updateDetails = function(values, newProp) {
                angular.forEach(values, function(value, index) {
                    newProp.found = false;
                    newProp.datas = value.datas;
                    updateFiles(newProp);
                });
            };

            return {

                savePref: function(newProp) {
                    Restangular.all('rest/savePref').post(newProp).then(function(response) {
                        $rootScope.success = true;
                    }, function(errorResponse) {});
                },

                saveDetails: function(values, prop) {
                    var newProp = {};
                    newProp.values= prop.values;
                    newProp.oldFiles = prop.oldFiles;
                    newProp.newFiles = prop.newFiles;
                    updateDetails(values, newProp);
                    this.savePref(newProp);
                }
            };
        });

My Jasmine Test cases:

describe('Service: SavePref', function(SavePref) {
    beforeEach(module('com'));

    var httpBackend;
    var RestangularMock;

    var values;

    beforeEach(function() {
        values = {
            datas: {
                file1: 'Test1',
                file2: 'Test2',
                file3: 'Test3'
            }
        };
        prop = {
            oldFiles: 'sampleFile1',
            newFiles: 'sampleFile2',
            values: {}
        };

        module(function($provide) {
            $provide.value('prop', prop);
        });
    });

    describe('Testing saveDetails Functions', function() {
        it('should save details when SaveDetails is called', inject(function(SavePref) {

            SavePref.saveDetails(values, prop);
            expect(updateDetails).toHaveBeenCalled();
            expect(SavePref.savePref).toHaveBeenCalled();
        }));
    });
});

Answer №1

To anticipate, you must first create a spy:

it('should save details when saveDetails is called',inject(function(SavePref) {

        spyOn(SavePref, "savePref").and.callThrough();
        SavePref.saveDetails(values, prop);
        expect(SavePref.savePref).toHaveBeenCalled();
    }));

If you wish to anticipate updateDetails, you need to make it public.

In my example, I used .and.callThrough(); without it, the call to the actual function is never made. You may choose to remove it as needed.

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 other technique can I use to replace the creation of a jquery division?

I`m relatively new to all things related to web technologies and I am currently practicing and learning about them. On my practice page, I've experimented with various elements, including changing div heights based on the viewport height. Here's ...

Can you import folders containing *.vue files in your project?

Repeating code is my least favorite thing. Currently, I am importing vue files in a repetitive manner in my main.js file. import Default from '../../src/components/default.vue'; import Home from '../../src/components/home.vue&apo ...

The Vue.js application which utilizes Vue I18n encountered the error message: "Unable to define i18n due to TypeError"

I am currently working on implementing internationalization in my Vue.js project using Vue I18n. Although I've been following the documentation found at , I encountered the following error message: [Vue warn]: Error in render: "TypeError: i18n is un ...

Ways to select a random row from a MySQL database

<button onclick="myUniqueFunction()">Press here!</button> <?php function myUniqueFunction() { $con = mysqli_connect("mysql.hostinger.no", "u452849516_altge", "password", "u452849516_altge"); $query = "S ...

Issues with the HTML5 progress bar malfunctioning due to alterations made by Angular

Using the html5 progress bar <progress value="5" max="100"></progress> in angular can lead to it being replaced by angular classes. Angular also has its own progress bar that uses similar tags. However, elements like the html5 slider do not get ...

How can one HTML form be used to request a unique identifier from the user, retrieve a record from the database, parse it into JSON format, and then populate an HTML page form using the

As someone who isn't an expert in any specific coding language, I have a knack for piecing things together to make them work. However, my current challenge is stretching my technical abilities a bit too far. Here's what I'm trying to achieve ...

Assigning alphanumeric characters to the axis for identification purposes

review the code in index.html <!DOCTYPE html> <html> <head> <title>D3 test</title> <style> .grid .tick { stroke: lightgrey; opacity: 0.7; } .grid path { stroke-width: 0; } .ch ...

The findByIdAndUpdate() function lacks the ability to modify the collection

I'm encountering an issue when trying to update a product using mongodb and redux. It seems that the database is not reflecting the changes after I attempt to update the product. Can someone please assist me with this problem? Here is my product.js f ...

Is there a way in JQuery to apply the CSS of one element to another selected element?

I'm curious if there is a JQuery function available that can be used to transfer the exact CSS styles from one element to another. I want all the CSS properties to be applied without any additional inheritance. For example: <div id="d1"> &l ...

Issue with Vue 2 emitting events and not properly executing associated method, despite correct setup

I am attempting to trigger an event from a child Vue component to its parent using this.$emit('collapsemenu'). However, when I try to capture this event in the parent using v-on:collapsemenu="collapseMenuf($event)", nothing seems to ha ...

Error: Unable to execute workouts.map as a function in "React" due to a TypeError

This is the JSON data retrieved from the server: {workouts: Array(3)} workouts: Array(3) 0: {_id: 'idnumber1', title: 'pullup', reps: 40, load: '20', createdAt: '2022-07-20T18:06:39.642Z', …} 1: {_id: 'idnumb ...

What is the best way to customize the appearance of an XML snippet using Greasemonkey?

I am attempting to customize an XML fragment retrieved from a server response using a Greasemonkey script. Take a look at this sample XML fragment from w3schools.com: <note> <to> Tove</to> <from>Jani</from> <heading ...

Guide on implementing ES6 script's template literals

I've been tackling a template literal question on hackerrank. It's working smoothly on my local IDE, but encountering an error on the Hackerrank IDE. Here's the code to add two numbers and print the result using a template literal: const sum ...

Unexpectedly, the NodeJS application experiences a crash following numerous requests

I can't seem to figure out why my Nodejs app crashes after a certain number of requests (currently 22). The issue arises with this simple get request handler: router.get('/api/docs/fetch', async (req,res) => { try{ let docs = ...

What is the best way to delete and add elements in a looped array using Javascript

i have a form similar to this one. https://i.sstatic.net/V7ivb.png how can I replace this form each time the country changes, by removing it and then appending it again from a looping array. If there is only one set of data, display an "Add Form" Button; ...

Having trouble with test coverage in Mocha using Blanket?

I have a Node application that I want to test and generate a coverage report for. I followed the steps outlined in the Getting Started Guide, but unfortunately, it doesn't seem to be working correctly. In my source code file named src/two.js: var tw ...

Gain access to Google Analytics without the need for page consent by utilizing JavaScript

I am currently building a dashboard with Atlasboard. My goal is to retrieve Google analytics data such as page views, and I plan to run specific queries which can be found here. Is there a method to access my Google analytics data without the consent pag ...

obtain data from an array using Angular 5

i need assistance with retrieving values from an array. Below is my code snippet: this.RoleServiceService.getRoleById(this.id).subscribe(data => { this.roleData.push(data['data']); console.log(this.roleData); }) however, the resulting ar ...

Is there a way to seamlessly transition the visibility of the Bootstrap 5.3 Spinner as it loads and unloads?

After delving into some research regarding Bootstrap-compatible spinners, I stumbled upon a piece of code. Take a look: function getData() { var spinner = document.getElementById("spinner"); spinner.style.display ...

Creating a primary index file as part of the package building process in a node environment

Currently, I have a software package that creates the following directory structure: package_name -- README.md -- package.json ---- /dist ---- /node_modules Unfortunately, this package cannot be used by consumers because it lacks an index.js file in the r ...