Executing test spec before promise resolution in $rootScope.$apply() is completed

When writing angular unit tests using Jasmine with angular-mocks' httpBackend, I successfully mocked my backend. However, one of my tests is encountering issues with an http call where a value is set to scope after the request is complete (in then()).

In the controller, $scope.startShift is bound to a button click.

 app.controller('ShiftStartCntl', function($scope, $rootScope, $location, Restangular, $http, shifts) {
    $scope.shifts = shifts;

    $scope.startShift = function (category) {
        $scope.startingShift = true;
        baseShifts.post({category_number: 2})
            .then(function (shift) {
                $scope.shift = shift;
                // breaks here if run as the endpoint isn't mocked
                $http.post('endpointThatIsNotMocked').then(function() {});
                $location.path($scope.rootURL + '/shift/' + shift.id + '/');
                $scope.startingShift = false;
        });
});

In the test:

// module definition and stuff
// 
// [...]
// 

describe('ShiftStartCntl', function() {
    var scope, rootScope, httpBackend, ShiftStartCntl;

    beforeEach(angular.mock.inject(function($rootScope, $controller, $httpBackend) {
        scope = $rootScope.$new();
        rootScope = $rootScope;
        httpBackend = $httpBackend;

        // mimics the controller's ng-route `resolve` dependency
        shifts = getJSONFixture('leave_shifts.json');
        scope.baseShifts = baseApi.all('shifts');
        // used in the controller
        scope.categories = getJSONFixture('leave_categories.json');

        httpBackend.expectPOST('/api/shifts/', {category_number: 2})
            .respond(203, {"id": 4,                                                                                                                                                                  "user": 1,
                "category_number": 2,
                "sign_in": "2015-02-10T21:29:06.110Z",
                "sign_out": null
            });

        $controller('ShiftStartCntl', {$scope: scope, shifts: []});
    }));

    it('should start a shift', function() {
        expect(shifts.length).toEqual(2);
        expect(scope.startingShift).toBe(undefined);
        scope.startShift(scope.categories[1]);
        rootScope.$apply();
        expect(scope.shift.id).toEqual(4);
        httpBackend.flush();
    });

});

The error message produced is:

PhantomJS 1.9.8 (Mac OS X) Shifts ShiftStartCntl should start a shift FAILED
        Expected undefined to equal 4.
            at [...]/js/tests/unit/controllers/main.js:100  
        Error: Unexpected request: POST yoyoyo

This occurs at the line where

expect(scope.shift.id).toEqual(4);
. The issue is that the error about the unexpected request should occur before
expect(scope.shift.id).toEqual(4);
is executed.

Despite trying suggestions from Stackoverflow answers and blogposts, such as using $rootScope.apply();, the problem remains unsolved. Any ideas on how this could be resolved?

Answer №1

Could you possibly relocate the httpBackend.flush(); line two lines up?

        scope.startShift(scope.categories[1]);
        httpBackend.flush();
        rootScope.$apply();
        expect(scope.shift.id).toEqual(4);

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

Generating procedural textures for particles within the context of three.js

I am working towards creating a particle system that involves procedurally generated textures for each particle's vertices. However, I am facing challenges in developing a prototype that can function seamlessly under both the Canvas and WebGL renderer ...

Create a new storefront JavaScript plugin for Shopware 6 to replace the existing one

I am attempting to replace an existing JavaScript plugin in Shopware 6. However, the code within the plugin file does not seem to execute. Here is my main.js: import MyCookiePermissionPlugin from './plugin/my-cookie-permission/my-cookie-permission.pl ...

Can the front end acquire JSON data from a URL, save it as a JSON file with a unique name, and store it in a designated location?

I'm facing a straightforward problem with my React Native project. I am attempting to create a script that will be executed during the build process to fetch JSON data from a URL and then store it as a JSON file with a unique name in a specific direct ...

Reset the counter variable when a certain condition is met

I am facing an issue with my simple "pagination" counter that fetches the next page from an API. The problem arises when I switch between different categories, such as movies or series, because the counter does not reset. Instead of starting again from the ...

Tips to troubleshoot problem with Javascript ``addEventListener`` ``click`` not functioning

I've been attempting to incorporate the "addEventListener" feature into my code. Despite following an example, I can't seem to get it to work. Is there something I'm missing or doing wrong? <body> <div class="emoji-row ng-s ...

How does the performance contrast between "skip if condition" and "immediately return"?

Do you know if there is a performance variance between these two functions? function x() { var x = false; if(x == true) { ... Numerous lines, like 1 million ... } } function y() { var x = false; if (x != true) { retu ...

Issue with fading hover effect on links is not functioning

I recently implemented a fade link hover effect using the code snippet below: a:link {color:#333333; text-decoration: none; -o-transition:.5s; -ms-transition:.5s; -moz-transition:.5s; -webkit-transition:.5s; transition:.5s;} a:visited {color:#FF0033; ...

Learn how to create a logarithmic scale graph using CanvasJS by fetching data from an AJAX call

window.onload = function() { var dataPoints = []; // fetching the json data from api via AJAX call. var X = []; var Y = []; var data = []; function loadJSON(callback) { var xobj = new XMLHttpRequest(); xobj.overrideMimeType("applicatio ...

Exploring Angular and IONIC to obtain values for different categories

Currently, I am working on implementing a rating system in Ionic that is based on Angular. I am trying to capture the value for each category separately. For example, when I rate "animals," I want to retrieve the selected value specifically for animals. Si ...

Issue: Accumulated Unresolved Requests Karma

Trying to simulate an http request but encountering this error Error: Unflushed requests: 1 in /Users/..etc/angular-mocks.js Here is the relevant code snippet describe('Tests for Group Controller', function() { var $httpBackend; beforeEach ...

Unable to properly cancel a post request using abort functionality

In the process of building a Next.js app, I encountered an issue with calling a post request. I included a cancel button to halt the post request, and attempted to use abortController in conjunction with Axios (v1.4.0) to achieve this. Even though the &ap ...

Uploading profile images with AngularJS and Firebase

I am encountering an issue with my JavaScript image uploader. It successfully uploads an image and provides the image src, but I need to save this value in my FireBase DB for the current user that is being created. Initially, I attempted to output the img ...

During the execution of my asynchronous javascript, it interrupts the flow of the other function

How can I ensure that a function executes after another one in Vue.js? I've tried various methods like async/await, callback functions, and .then, but none seem to work seamlessly. Any suggestions for a possible solution? auth_util.js: async auth () ...

Working with the collapse event in Bootstrap

After purchasing a template from ThemeForest, I found it to be absolutely amazing. However, I am struggling with using Bootstrap as it seems quite complex. The left menu is structured with collapsible ul and multiple li elements. I am seeking assistance o ...

Automatic panning of JavaScript on a map

Having some issues with the functionality of the pan function. It's working, but not quite how I need it to. Currently, I have a logo overlaying a map and I want to pan away from the logo automatically to show an infowindow (panning left or right). H ...

Issues arise with the Node EJS module due to the malfunction of the include

Struggling with incorporating HTML snippets into my index.html, even after reviewing the EJS documentation. Directory Structure: project -public --assets ---css ---images ---js --Index ---index.html + index.css and index.js --someOtherPageFolder -views - ...

Managing the hovering of a mouse over an image within an isometric grid displayed on a

I have implemented an isometric grid in HTML canvas. My goal is to handle mouse hover events on the buildings within the grid. Some buildings will vary in heights. In the image below, you can see that when hovering over a tile, the highlighted area shif ...

What is the best way to interpret and execute conditions specified within strings like "condition1 and condition2"?

Received a JSON file from an external source with various conditions that need to be tested, either in real-time or through conversion. Imagine having an instance of a class called Person, with attributes {age: 13, country: "Norway"}, and an ext ...

AngularJS 2 treats lists as custom directives

I am working on developing an e-commerce website. The project involves displaying a list of goods and a basket (which contains selected goods). In order to achieve this, I have created a controller with two arrays: one for goods (already filled) and anothe ...

Selecting any of the bar chart labels will reveal just a two-day timeframe

My bar chart is behaving strangely - when I click on all labels, it only shows two days instead of updating as expected. I suspect it may be due to a bad implementation involving parsing. Can anyone provide assistance? I have created a minimum example on ...