Troubleshooting the issues with testing AngularJS using Jasmine and Karma, particularly when $httpBackend is

I'm currently in the process of writing unit tests for my Angular app using Jasmine with Karma. One of the functionalities of the app is to make a call to the GitHub API, retrieve a user's repository names, and store them in an array. Although I'm attempting to test that the array gets populated successfully, I'm encountering difficulties with $httpBackend.

The essential sections of my controller are as follows:

readmeSearch.controller('ReadMeSearchController', ['RepoSearch', function(RepoSearch) {

  var self = this;
  self.gitRepoNames = [];

  self.doSearch = function() {
    var namesPromise =
      RepoSearch.query(self.username)
        .then(function(repoResponse) {
          addRepoNames(repoResponse);
        }).catch(function(error) {
          console.log('error: ' + error);
        });
    return namesPromise;
  };

  addRepoNames = function(response) {
    self.repoSearchResult = response.data;
    for(var i = 0; i < self.repoSearchResult.length; i++) {
      var name = self.repoSearchResult[i]['name']
      self.gitRepoNames.push(name);
    };
  };

}]);

The RepoSearch factory is defined as:

readmeSearch.factory('RepoSearch', ['$http', function($http) {

  return {
    query: function(searchTerm) {
      return $http({
        url: 'https://api.github.com/users/' + searchTerm + '/repos',
        method: 'GET',
        params: {
          'access_token': gitAccessToken
        }
      });
    }
  };

}]);

Additionally, the relevant test code is provided below:

describe('ReadMeSearchController', function() {
  beforeEach(module('ReadMeter'));

  var ctrl;

  beforeEach(inject(function($controller) {
    ctrl = $controller('ReadMeSearchController');
  }));

  describe('when searching for a user\'s repos', function() {

    var httpBackend;

    beforeEach(inject(function($httpBackend) {
      httpBackend = $httpBackend
      httpBackend
        .expectGET('https://api.github.com/users/hello/repos?access_token=' + gitAccessToken)
        .respond(
        { data: items }
      );
    }));

    afterEach(function() {
      httpBackend.verifyNoOutstandingExpectation();
      httpBackend.verifyNoOutstandingRequest();
    });

    var items = [
      {
        "name": "test1"
      },
      {
        "name": "test2"
      }
    ];

    it('adds search results to array of repo names', function() {
      ctrl.username = 'hello';
      ctrl.doSearch();
      httpBackend.flush();
      expect(ctrl.gitRepoNames).toEqual(["test1", "test2"]);
    });

  });

});

Upon running the test, I encounter the following error:

Expected [ ] to equal [ 'test1', 'test2' ].

The issue seems to stem from self.gitRepoNames not being populated. Prior to the expectation in the test, when I log ctrl.repoSearchResult, I receive:

Object{data: [Object{name: ...}, Object{name: ...}]}

This leads me to believe that the problem lies in the fact that self.repoSearchResult.length is undefined when accessed within the for loop of the addRepoNames function.

Hence, my question is why does response.data not return an array when invoked in the addRepoNames function during the test?

Any assistance on this matter would be greatly appreciated.

EDIT: It's worth noting that the app functions correctly when executed on the server.

Answer №1

ctrl.performSearch is a function that operates asynchronously. It is important to approach it using an asynchronous method. Here's an example:

it('populates array with search results', function(done) {
  ctrl.username = 'hello';
  ctrl.performSearch().then(function() {
    expect(ctrl.repoNames).toEqual(["result1", "result2"]);
    done();
  });
  httpBackend.flush();      
});

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

Opting for frontend technologies such as React or Angular to update a Silverlight application containing over 1000 unique forms and views

We are in the process of transitioning our Silverlight application to modern web technologies like React or Angular due to the impending end of life for Silverlight by the end of this year. We are seeking advice on selecting the most suitable frontend tec ...

Ajax is updating the information stored in the Data variable

Recently, I reached out to tech support for help with an issue related to Ajax not executing properly due to Access-Control-Allow-Origin problems. Fortunately, the technician was able to resolve the issue by adding a file named .htaccess with the code Head ...

Scroll down only if the user is not actively scrolling

Struggling with JavaScript once again and feeling frustrated! Can someone please assist me? I am currently working on a basic chat application that retrieves content from a text file using an AJAX request. The content refreshes every few seconds, scrollin ...

Real-time chat system using PHP for one-on-one inquiries with server-sent events (not a group chat)

I'm currently working on developing a live chat inquiry form for a website using HTML server-sent events. I'm utilizing this tutorial as a foundation Here is my plan based on the tutorial: On the client side, users are prompted to enter a use ...

`How to resolve page timeout issue caused by looping when using Response.Redirect?`

Currently, I am in the process of building a page that involves creating a large number of files within a folder. Once the task is completed, I compress the folder into a zip file and provide the client with a download link. To keep track of these files, I ...

Struggling to make the DataTables.net Bootstrap 5 example function properly

I'm currently working on familiarizing myself with the styling example for Datatables.net using Bootstrap 5, which can be found at https://datatables.net/examples/styling/bootstrap5.html. I've followed the code provided in the example closely, bu ...

The for loop in JavaScript fails to verify the contents of an array and instead shows a message in a designated

The message for leap year is not appearing in the designated element Uncertain why the message isn't showing after the for loop const year = [2020, 2021, 2022, 2023, 2024, 2025, 2026, 2027, 2028, 2029, 2030, 2031, 2032]; for (var i = 0; i < ye ...

"Encountered an issue while serializing the user for session storage in Passport.js. Have you already implemented code for

I have recently started learning nodejs and I am currently working on creating a login system. I followed the code for serializing the user from the passport documentation and placed it in config/passport.js. However, I keep encountering the error "Failed ...

Unable to connect beyond the local network using Socket.io

server.js import { Server } from "socket.io"; const io = new Server(8000); io.on("connect", (socket) => { console.log(`connect ${socket.id}`); socket.on("ping", (cb) => { console.log("ping"); ...

Customize Your Chrome Experience: Inject an Element to Open a Hidden HTML Page within the Extension

I am currently working on a Chrome extension and I would like to add a link tag into an object, which will then direct the user to an about page stored within the extension itself. Is there a way to achieve this? Below is the code from my content.js file: ...

What steps can I take to minify my code using react-create-app?

Currently, I am facing an issue with minifying my code on the server. Despite running npm run build, which is supposed to handle all the minifying processes (as shown here: https://i.stack.imgur.com/wjpd7.png), I still see the unminified code when accessin ...

Changing buffer from base64 to UTF-8 encoding in Node.js

My application imports messages from the Notes folder of Gmail using the imap npm module. When following the example on their GitHub page, all message contents are read into a buffer: stream.on('data', function(chunk) { count += chunk.len ...

Export data from a JSON object to a CSV file within the Osmosis function

I am currently utilizing Osmosis, a node.js tool, to extract data in the form of an array of JSON objects. The behavior of Osmosis functions indicates that the array is confined within the function's scope. Consequently, I must also write the file in ...

Locating the matching value in the <select> element and showcasing it

I'm trying to create a function where selecting an option from one dropdown menu will display the corresponding value in another column. For instance, if someone chooses "3" from the first dropdown, the value displayed in the third column should be "3 ...

Creating a binary tree in vanilla JavaScript and styling it with HTML and CSS

I'm facing a challenge with my homework. I am required to convert my JavaScript binary tree into HTML and CSS, strictly using vanilla JavaScript without any HTML code. I have the tree structure and a recursive function that adds all the tree elements ...

Interact with jQuery to trigger events upon clicking on a list item, excluding checkboxes within the list

I'm in the process of developing a straightforward web application. I have a dynamically generated list on one section: Subsequently, I set up an event that triggers when any element within the list is clicked: $(document).on('click', &apo ...

Highlighted option selection in Material UI dropdown using Cypress

Can someone explain how to select Material-UI dropdown options using Cypress? I'm looking for a simple explanation, thanks! ...

Managing Forms in AngularJS is crucial for creating user-friendly

Exploring the possibility of integrating Angular with Django for form handling. Is there a way to bind form elements without manually adding ng-model to each input field? Here's what I'm aiming for: <form name="myForm" ng-submit="submitForm( ...

The value of the keycode is consistently 229 for all keys

While using the regular textbox on my android device, I encountered some problems which are listed below. 1. The keypress event is not triggered on the android device. 2. The keycode value always returns as 229. What are some possible solutions to resolv ...

A guide on how to modify a CSS property to set the display to none upon clicking a radio button

Currently, I am attempting to display two input boxes in a table when I select specific radio buttons and hide them if I choose another option. The code I have does work but has a minor issue, function disappear() { document.getElementsByClassName("ta ...