Exploring the power of Jasmine with multiple spy functionalities

I'm currently working on writing unit tests for an Angular application using Jasmine, specifically focusing on testing different scenarios within a function. The main challenge I am facing is structuring the test to accommodate various conditions such as the if statement and callbacks.

The $scope function in question takes an Object as input. If the object contains an id, it updates the existing object. Otherwise, it creates a new report and sends it to the backend using the CRUD service.

$scope.saveReport = function (report) {
  if (report.id) {
    CRUD.update(report, function (data) {
      Notify.success($scope, 'Report updated!');
    });
  } else {
    CRUD.create(report, function (data) {
      $scope.report = data;
      Notify.success($scope, 'Report successfully created!');
    });
  }
};

One of my tests involves passing a mock Object with an id to trigger the CRUD.update method, which I then verify has been called.

describe('$scope.saveReport', function () {
  var reports, testReport;
  beforeEach(function () {
    testReport = {
      "id": "123456789",
      "name": "test"
    };
    spyOn(CRUD, 'update');
    $scope.saveReport(testReport);
  });
  it('should call CRUD factory and update', function () {
    expect(CRUD.update).toHaveBeenCalledWith(testReport, jasmine.any(Function));
  });
});

While I understand that Jasmine does not support multiple spies, I still want to find a way to test the if condition and also create a mock test when the Object does not include an id:

describe('$scope.saveReport', function () {
  var reports, testReport;
  beforeEach(function () {
    testReport = {
      "id": "123456789",
      "name": "test"
    };
    testReportNoId = {
      "name": "test"
    };
    spyOn(CRUD, 'update');
    spyOn(CRUD, 'create'); // TEST FOR CREATE (NoId)
    spyOn(Notify, 'success');
    $scope.saveReport(testReport);
    $scope.saveReport(testReportNoId); // TEST FOR NO ID
  });
  it('should call CRUD factory and update', function () {
    expect(CRUD.update).toHaveBeenCalledWith(testReport, jasmine.any(Function));
    // UNCERTAIN ABOUT THIS PART AS WELL
  });
});

I have read about using the .andCallFake() method but unclear on how to apply it in my specific case. Any guidance would be greatly appreciated.

Answer №1

When determining what to test first, consider focusing on whether the update function is called when the id exists or if the create function is called when it doesn't. Structure your testing functions accordingly and remember that the before each block may not always be the best place for certain actions.

it('should invoke CRUD factory and execute update', function () {
    spyOn(CRUD, 'update');
    $scope.saveReport(testReport);
    expect(CRUD.update).toHaveBeenCalledWith(testReport, jasmine.any(Function));
});
it('should invoke CRUD create', function() {
    spyOn(CRUD, 'create');
    $scope.saveReport(testReportNoId); // TESTING FOR NO ID
    expect(CRUD.create).toHaveBeenCalledWith(testReport, jasmine.any(Function));
});

Only include necessary actions in the before each block that are required before each test case.

I hope this explanation has been beneficial!

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

The Nuxt authentication middleware fails to function properly upon clicking the back button in the browser

When it comes to implementing the protected route in Nuxt, I have found that using middleware is the best approach. In my implementation, I utilized the cookie-universal-nuxt module. Everything was running smoothly until I encountered a bug. When a user&a ...

An issue arises when attempting to iterate over an object literal using ng-repeat in AngularJS

I am currently learning angular js and practicing filters. I have successfully been able to iterate over an array of objects, but when trying to work with objects within objects, my browser is throwing an error: "Uncaught SyntaxError: Unexpected token" &l ...

Issue with Repeated String Test in JavaScript: Single Failure Detected

Currently tackling the Repeated String Challenge on HackerRank. The challenge description goes as follows: A string, denoted by s, consisting of lowercase English letters is repeated infinitely. With an integer, n, the goal is to determine and output the ...

Capture locations from Google Maps

What is the best method to extract all addresses, along with their latitude and longitude, for a specific city (such as Bangalore) from Google Maps using PHP/JavaScript and store it in a MySQL table? I urgently need assistance. Thank You ...

Unable to attach an onClick event handler to <TableRowColumn> element using Material-UI in React

In the past, I had a feature that allowed me to change the color of the text from red to green by clicking on a table cell. After introducing Material-UI in my React app and replacing the <td> tags with <TableRowColumn> tags, I noticed that th ...

The absence of the function crypto.createPrivateKey is causing issues in a next.js application

For my next.js application, I am utilizing the createPrivateKey function from the crypto module in node.js. However, I encountered an issue as discussed in this thread: TypeError: crypto.createPrivateKey is not a function. It seems that this function was a ...

A Vue element that has multiple exact click handlers will consistently trigger the click.exact method when clicked with system modifiers

According to the information found at https://v2.vuejs.org/v2/guide/events.html#exact-Modifier, I am attempting to build an element that triggers different methods based on additional keys pressed at the time of clicking. <span @click.exact="method ...

Inconsistent CSS3 transitions behavior in Firefox 4

I have been playing around with some css3 transitions and created a slider test. It works perfectly in webkit browsers, but I have noticed an issue in Firefox 4. When clicking on the left link for the first time, the slider is supposed to slide to the left ...

Executing a function upon the loading of a template in AngularJS

I have been searching through various responses here, but I haven't come across one that addresses my specific problem. Apologies if this has already been answered. I am a beginner in angular js and have recently begun working on angular routing. I am ...

The angular bootstrap typeahead feature is experiencing issues when used with a dynamic list that is fetched through the ng

Currently, I am utilizing the typeahead directive in angular-bootstrap. My issue arises when a user changes the input; I aim to trigger an ng-change event to retrieve a list from the server and subsequently filter the results. Once accomplished, I want to ...

What is causing myInterval to not be cleared properly?

const homeButton = document.getElementById('home'); window.myInterval = 0; const showHome = () => { console.log('showHome'); window.myInterval = setInterval(wait, 400) } const wait = () => { console.log('wait'); ...

Issue encountered while retrieving information from XML file through AJAX

I am facing an issue while using AJAX to fetch data from an external XML file. The error I receive is "Invalid argument" and I am working with IE 8. Below is the code snippet: var xhr; xhr = new XMLHttpRequest(); xhr.open("GET","C:/Users/abc/Desktop/Pr ...

Having trouble getting the expected transition effects to work with Vue.js

Currently, I have a display of lists of items through the use of v-for. Initially, only the summary section of each item is visible. Upon clicking on an item, the details section is supposed to appear. This functionality is achieved by adding or removing ...

Developing pagination functionality in ReactJS

I came across this piece of code in a forum (how to implement Pagination in reactJs): constructor() { super(); this.state = { todos: ['a','b','c','d','e','f','g','h ...

Encountered an unanticipated symbol at column 2 while using the Angular Google Recaptcha

I have integrated the Angular Google Recaptcha directive into my application from https://github.com/VividCortex/angular-recaptcha. However, upon running my application, I encountered an error stating that I am using my public key instead of my private key ...

Can you explain the significance of "@c.us" in the context of whatsapp-web.js?

Are there any references or resources available for using "@c.us" that I can consult? Here is an example: client.on('ready', () => { console.log('Client is ready!'); // Your message. const text = "Hey John"; // Obt ...

Tools for parsing command strings in NodeJS

Currently, I'm utilizing SailsJS for my application. Users will input commands through the front-end using NodeWebkit, which are then sent to the server via sockets. Once received, these commands are parsed in the back-end and a specific service/cont ...

PHP isn't getting the AJAX POST data from the JavaScript file

I've been stuck on this issue for hours now, unable to find a solution. Here is the javascript code snippet: function sendMovement(cel) { var name = "test"; $.ajax({ type: 'POST', url: '../game.php', ...

javascript href clears Internet Explorer webpage

I noticed a strange issue with my HTML page. In Internet Explorer, when I click on the link, it displays the return value on a blank page. However, in Chrome, it simply executes the function without affecting the page appearance. Is there a way to make I ...

Issues with unresponsive buttons in AngularJs

In creating a basic registration page, I encountered a strange issue with the button functionality. Whenever I attempt to submit the form, an error should be logged to the console. However, the buttons on the registration page appear to be inactive - it se ...