Exploring the execution of internal methods within an Angular service

My service is a simple one for Shoes

app.factory('Shoes', function() {
    function x() {return 12;}
    function y() {return x();}

    return {
      x: x,
      y: y
    }
  })

I am trying to verify if the method x gets called when I invoke method y. My test case is as follows:

describe('Testing a Shoes service', function() {
  var service;

  beforeEach(module('plunker'));

  beforeEach(inject(function(Shoes) {
    service = Shoes;
  }))

  it('.y should call .x', function() {
    spyOn(service, 'x');
    service.y();
    expect(service.x).toHaveBeenCalled();
  })

});

However, the tests are not passing. You can view the relevant Plunker here.

How can I effectively test these types of interactions?

Answer №1

When setting a spy on the service.a method, it's important to note that the internal a (which is called internally by b) remains the same internal method and not the spy. This can cause your test to fail.

If you want to ensure the spy is being called, avoid calling the internal a, and instead call the method of your service directly:

app.factory('Shoes', function() {
    return {
        a: function a() {
            return 12;
        },

        b: function b() {
            return this.a();
        }
    };
});

An updated version of the code can be found here: https://plnkr.co/edit/6FZptdcX9qwyOE6kbgAX

EDIT:

To clarify, the service.a method serves as a pointer to the internal a method. By using spyOn(service, 'a'), you're essentially changing where service.a points to, creating a new spy method with jasmine. Since the internal a method is private and static, it will remain unchanged even after spying on service.a. Therefore, calling a() within the internal b method will execute the original a method rather than the spy referenced by service.a.

Answer №2

After some troubleshooting, I was able to resolve the issue using the code snippet below:

app.factory('Shoes', function() {
    var module = {
      a:function(){
        return 12;
      },
      b: function(){
        return this.a();
      }
    }
    return module;
});

It appears that the tested module must not simply call a "function", but rather should call the method of the object returned;

Check out the updated Plunker here: https://plnkr.co/edit/DeDmdQq3rguO6uGHElW6?p=preview

Answer №3

app.service('Footwear', function() {

var model = {
  x: function() {return 12;},
  y: function() {return this.x();}
}

return {
  x: model.x,
  y: model.y
}
})

It seems like the issue is that function b is not correctly invoking the function being spied on. When using the service method as shown above, the test passes successfully.

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

How can I incorporate the Three.js scene demonstration into Vue 3?

Looking to integrate the Three.js beginner example for creating a scene [1] into a Vue.js 3 project using JavaScript (not TypeScript)? [1] main.js import * as THREE from 'three'; const scene = new THREE.Scene(); const camera = new THREE.Perspe ...

Using AJAX in JavaScript to call a webmethod in ASP.NET that is not static

Similar Question: Executing non-static method in aspx.cs from client side using javascript (aspx) The code snippet below is currently functioning correctly function getFooObj() { $.ajax({ type: "POST", url: "Dummy.aspx/GetFooObj", ...

How to retrieve the parent index from within a nested forEach loop in JavaScript

var game_board = [ [1, 2, 3], [4, 5, 6], [7, 8, 9], ]; (function iterate() { game_board.forEach((row, i) => { row.forEach((value, j) => { // accessing indexes i and j console.log(i, j); }); }); })() I have a two-dimens ...

Transforming an unconventional date format into a proper date representation

I have a spreadsheet with over 100,000 dates stored in the following format: Thursday 29th of October 2015 01:06:21 PM Converting these dates into a usable format is proving to be a challenge. Whether it's YYYY/MM/DD or any other standard format, I ...

Encountering [object, Object] while attempting to display JSON object retrieved from req.body in the console

While attempting to insert a product's details into my API's PostgreSQL database using Postman, I encountered an issue where the values of the specs key were displayed as [object Object] instead of showing the complete data. As a result, even in ...

One clever AngularJS hack

Can anyone help me figure out how to call a function in a controller specifically for the first 'li' element in a 'ul' that is using ng-repeat? For example, I have a function in my controller: var init = function () { var a = this; ...

Can JSON data be exported to docx, pdf, and excel files using node.js or client-side JavaScript?

I have been searching for a method to export JSON data into three main formats, including docx, xlsx, and pdf. Thus far, I have managed to achieve this in Node.js: var data = req.body["exportData"]; var headers = req.body["exportHeaders"]; var delimite ...

Display the outcomes of two MongoDB queries simultaneously on a single page

As I dive into the world of MongoDB and Node.js/Express, I find myself struggling to fully grasp some of the concepts. Forgive my inexperience, but I haven't been able to locate a clear answer for what I'm trying to achieve. My goal is straight ...

Select and emphasize specific sections of text

Can I create an input element that looks like the one in my screenshot? I want to be able to change the value with JavaScript and highlight text by wrapping it with '*' and giving it a different color. Thank you for any assistance. ...

Encountering a TokenMismatchException when using javascript x-editable in Laravel 5.3

Despite trying various solutions from different sources, such as SO, none of them were able to resolve the issue before marking it as duplicated. Currently, I am utilizing the x-editable plugin to save a new record through a store route. After submitting ...

Encountering a 404 error indicating that the file cannot be found while attempting to log into an authentication system developed using express and node

Currently, I am in the process of developing a demonstration banking application that facilitates user sign up and sign in functionality using express.js and node.js. The API created accepts POST requests to /signup and /authenticate routes successfully wh ...

Guide on utilizing personalized fonts with Handlebars and Puppeteer

I have a Handlebar template that I am converting to PDF using Puppeteer. My question is how can I incorporate custom fonts? Currently, I have a static folder declared in my app.js file like this: app.use(express.static(path.join(__dirname, 'assets&ap ...

Tips for managing the sequence of chosen items

Currently, I am utilizing the react-dropdown-tree-select component in my project. I have a question regarding changing the order of selected items. The current default behavior is for the selected item order to match the data list order. However, I woul ...

Transmitting information together with FormData as a single entity through AJAX

I'm attempting to transmit a FormData within a JSON array to an AJAX script: $('#form').submit(function(e) { e.preventDefault(); let formData = new FormData(this), data = {'action': 'insert', 'data& ...

What could be causing my textarea-filling function to only be successful on the initial attempt?

Programming: function updateText() { $("body").on("click", ".update_text", function(event) { $(this).closest("form").find("textarea").text("updated text"); event.preventDefault(); }); } $(document).ready(function() { updateText(); }); H ...

What is the preferred method for implementing a dynamic select control with Ajax

I'm having an issue with AJAX and MySQL in PHP. Can anyone offer assistance? Within my form, I have a select control: <form action="index.php" method="post" name="pretraga" class="border"> <p>Location:</p> <div ...

Utilizing AjaxChosen for event handling

I am currently experimenting with a jQuery plugin that can be found here: https://github.com/meltingice/ajax-chosen. I have a multiple select field and I am curious about which event is triggered when a user either deletes or selects a value. Here are the ...

What is the best method for eliminating the default title in selectpicker?

I'm currently working on integrating angular selectpicker into my project. Initially, everything was displaying correctly as shown below: <select class="selectpicker"> <option>Mustard</option> <option>Ketchup</opti ...

What is the method to trigger a function upon opening an anchor tag?

When a user opens a link in my React app, I need to send a post request with a payload to my server. My current strategy involves using the onClick and onAuxClick callbacks to handle the link click event. However, I have to filter out right-clicks because ...

How to access ng-model value within ng-repeat with ng-change

Hey everyone, I'm new to working with Angular and I've been facing some issues trying to retrieve the value of ng-model from within ng-repeat. Currently, I have an array of users and my goal is to assign different access levels to each user use ...