The error message encountered states that Jasmine is unable to perform the act of throwing a spy

I'm working on an Angular JS application that includes a module and some services. The controller in my app utilizes these services. In my Jasmine test cases, I decided to create a mock of one of the services using Jasmine's createSpy function. Here is how I mocked the service:

beforeEach(module(function ($provide) {
    shoppingData = function () {
        getAllItems: jasmine.createSpy('getAllItems');
        addAnItem: jasmine.createSpy('addAnItem');
        removeItem: jasmine.createSpy('removeItem');
   };
   $provide.value('shoppingData', shoppingData);
}));

The controller triggers the getAllItems function right after creating an object. So, I set up another beforeEach block to instantiate the controller object. Below is the test case to verify if the getAllItems function is called:

it("Should call getAllItems function on creation of controller", function () {
    expect(shoppingData.getAllItems).toHaveBeenCalled();
});

However, when I run the spec runner page in the browser, the test fails with this error message: TypeError: 'shoppingData.getAllItems' is not a function.

I've seen similar examples where this type of test works flawlessly. Can someone help me spot what might be missing or going wrong here?

Update: I have uploaded a plunker showcasing the problematic section

Answer №1

It appears there may be a typo in the original code. Consider making the following adjustment:

shoppingData = {
  getAllItems: jasmine.createSpy('getAllItems'),
  addAnItem: jasmine.createSpy('addAnItem'),
  removeItem: jasmine.createSpy('removeItem')
};

Instead of defining functions, I changed them to properties within an object and replaced the semicolons with commas.

UPDATE 1:

Focus spying on the existing object only:

var deferred, _shoppingData;

beforeEach(module('shopping'));

beforeEach(inject(function(shoppingData, $q) {
  _shoppingData = shoppingData;
  deferred = $q.defer();
  spyOn(shoppingData, 'getAllItems').andReturn(deferred.promise);
}));

it('should have called shoppingData.getAllItems', function() {
  expect(_shoppingData.getAllItems).toHaveBeenCalled();
});

Answer №2

Have you considered attempting this approach:

let currentScope, sampleController;

beforeEach(inject(function($rootScope, $controller) {
  currentScope = $rootScope.$new();
  sampleController = $controller('sampleController', {
    $scope: currentScope,
    shoppingData: jasmine.createSpyObj('shoppingData', ['getAllProducts', 'addProduct', 'removeProduct'])
  });
}));

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

Why is $rootScope in AngularJS still undefined in the Controller even after injection?

In the realm of ionic / angularJS, I have embarked on a petite project geared towards a mobile application. The task at hand involves reading a JSON file located in the same directory as index.html, aiming to assign it to a $rootScope variable within the ...

Bypass JWT signature verification in Nestjs with passport-jwt

I am faced with a challenge where I need to access a user's secret stored in Redis by parsing the token body. Is there a more elegant solution available without having to write an entire new strategy from scratch? I am using nestjs for my architecture ...

Bizarre actions with jQuery append in Internet Explorer 8

Issue with adding elements to a div in IE8: The element is not added until the button is clicked twice, resulting in two new elements being added at once. Here's the code snippet in question: $(options.addButton).click(function(event) { var proto ...

Is utilizing react State recommended for managing class addition and removal?

Utilizing the intersection observer to dynamically add and remove classes allows me to initiate animations when specific divs become visible in the viewport. A great example of this technique can be seen on a website like , where scrolling triggers animate ...

What is the best way to extract text/html that appears between two consecutive <input> tags?

Is there a straightforward method to extract the text or HTML content located between input tags, even though these tags do not require closing tags? For instance, in the example below, I am looking to retrieve <b>Bob and Tim</b><br>Tim & ...

show small previews of pictures stored in a JavaScript array by using a for-loop

Currently stuck on a university project where I've set up an array of images like this: var testdata = [ { "imageID": 17, "uploadedDate": "2020-07-31 03:56:56.243139", "filepathOriginal": &qu ...

Timer countdown: Looking for a countdown timer that will reset to 3:00 automatically each time it reaches 0 minutes, and can do so

Seeking a continuous countdown timer that starts from 03:00 and counts down to 0:00, then automatically resets back to 03:00, in an infinite loop. The condition is that no one should be able to manually stop this logic. After researching, I found a Ja ...

"Customizable rectangular container with jagged edges created with Scalable Vector Graphics

Currently, I am undertaking a small project that involves creating a box with rough edges around some text. To achieve this effect, I am utilizing an SVG with unique edges similar to the design found at this link: (except mine is in SVG format). My goal ...

The hyperlink element is failing to load in a particular frame

I've been attempting to load the URL of an anchor tag in a specific frame. I've tried various methods through online searches, but have not found a satisfactory solution. Can someone please assist me with how to load the href URL in a particular ...

A JavaScript pop-up box with two windows

Struggling to create two separate dialog boxes using this code. The issue is that when I add the code for the second dialog box, it only appears if the first one does too. Here's the code for the first dialog: function showPopUp(el) { var ...

Using ASP.NET page: executing Javascript function upon receiving file download response from the server

I am facing a situation with my ASP.NET page where the server returns either a new page or a file for download after a request is made. I would like to display a "Processing..." message on the screen while the data is being retrieved from the server. It&a ...

Sending numerous arguments via HTTP DELETE request

In my code, I am trying to send the id and dept fields in a DELETE HTTP request and then retrieve them inside the deleteData() function. However, I am encountering an issue where the values for id and dept are coming up as null within the deleteData() fu ...

Javascript: Troubleshooting Unexpected Variable Behavior in HTML Code

My issue is as follows: I am attempting to retrieve text from a JSON file in my HTML. In the header of my HTML, I have linked a tag with the following code: var language = ""; var langDoc = null; //Function to change the value function setLang() { v ...

Trouble encountered with card flip style login form in Vue.js, as the card is not maintaining its position properly during transition animations

Need help styling a login/signup component in Vue.js where flipping between the two cards isn't working smoothly. The transition is causing one card to move down and right while the other comes in from the bottom right. It's hard to explain the i ...

Manipulating the InnerHTML content of a total of 144 individual cells

I am currently developing a tile-based game using tables. Each td cell contains the following code: <td> <div id="image" style="display:none; display: fixed; right: 5; top:2;"><img src="http://thumb7.shutterstock.com/display_pic_with_logo ...

Utilizing Conditional Statements in the @artsy/fresnel Framework

I recently started working on a responsive React application using the @artsy/fresnel npm package. Below is a snippet of the code I have implemented: <Media greaterThanOrEqual='computer'> <div style={{ padding: '20px 50px' ...

Identifying overflow of text or elements in JavaScript during execution

The website I'm working on has a unique design that requires users to scroll horizontally using the Arrow Keys instead of swiping. To achieve this, I must constantly check for overflow in text or elements each time a new page is loaded, and if necessa ...

Excluding generated js and js.map files from TFS in .Net Core and Typescript

I'm currently working on a .NET Core project and looking to integrate TypeScript into it. However, I am encountering issues with excluding the generated .js and .js.map files from being included in check-ins. After attempting the tfignore method ment ...

Try implementing toggleClass() in the accordion feature rather than addClass() and removeClass()

Hey there! I've implemented accordion functionality using the addClass() and removeClass() methods. Here's a breakdown of what I did: <div class="container"> <div class="functionality">Accordion</div> <ul class="acco ...

Enhance Your Website with Interactive Tooltips Using Twitter Bootstrap

In Twitter bootstrap, the default trigger for tooltips is hover. If I want to make the tooltip display on focus instead, I can add data-trigger="focus". But how do I make it so the tooltip displays both on hover and on focus? ...