Exploring the functionality of closing a modal in Karma-Jasmine testing

THE ISSUE AT HAND:

In my Angular / Ionic app, I am currently in the process of testing a modal to ensure it is functioning correctly.

While I have successfully tested that the modal opens as expected, I am facing difficulties in testing the proper closing of the modal.

Despite multiple attempts and researching similar inquiries, I have yet to find a viable solution.

THE CODE IN QUESTION:

The controller:

The code functions properly within the application but has been refactored for ease of unit testing.

$scope.open_login_modal = function() 
{
    var temp = $ionicModal.fromTemplateUrl('templates/login.html',{scope: $scope});

    temp.then(function(modal) { 
        $scope.modal_login = modal;
        $scope.modal_login.show();
    });
};

$scope.close_login_modal = function() 
{
    $scope.modal_login.hide();
};

The test:

The initial test (opening the modal) executes smoothly and passes. However, I am stuck on how to proceed with the second test.

describe('App tests', function() 
{
    beforeEach(module('my_app.controllers'));

    // mocking the .then method of $ionicModal.fromTemplateUrl (it works)
    function fakeTemplate() 
    {
        return { 
            then: function(modal){
                $scope.modal_login = modal;
            }
        }
    }

    beforeEach(inject(function(_$controller_, _$rootScope_)
    {
        $controller = _$controller_;
        $rootScope = _$rootScope_;
        $scope = _$rootScope_.$new();

        $ionicModal = 
        {
            fromTemplateUrl: jasmine.createSpy('$ionicModal.fromTemplateUrl').and.callFake(fakeTemplate)
        }; 

        var controller = $controller('MainCtrl', { $scope: $scope, $rootScope: $rootScope, $ionicModal: $ionicModal });
    }));


    describe('Modal tests', function() 
    {
        it('should open login modal', function() 
        {
            $scope.open_login_modal();

            expect($ionicModal.fromTemplateUrl).toHaveBeenCalled();
            expect($ionicModal.fromTemplateUrl.calls.count()).toBe(1);
        });

        it('should close login modal', function() 
        {
            $scope.close_login_modal();
            // How can i test here that the modal has been close?
        });
    });

});

THE ERROR ENCOUNTERED:

An error message stating:

TypeError: Cannot read property 'hide' of undefined

THE QUERY:

I am seeking guidance on how to effectively test the closure of the modal. How can I confirm that the hide() function has been executed correctly?

Is the issue related to how the modal is declared in the test?

Thank you for your assistance!

UPDATE:

This response adequately addresses the query regarding testing the closure of a modal by suggesting a proper solution to include before opening the modal. For insights on efficiently spying on a modal, a separate inquiry has been raised:

Karma-Jasmine: How to properly spy on a Modal?

The provided answer also offers a guideline on general premise spying techniques.

Answer №1

Your close test is dependent on the modal login being opened. However, since the modal is not opening as expected, you are encountering an error:

To resolve this issue, I suggest rewriting your test as follows:

describe('Modal tests', function() {
  beforeEach(function(){
    $scope.open_login_modal();
  });
  it('should open login modal', function() {
    expect($ionicModal.fromTemplateUrl).toHaveBeenCalled();
    expect($ionicModal.fromTemplateUrl.calls.count()).toBe(1);
  });
  it('should close login modal', function() {
    $scope.close_login_modal();
    spyOn($scope.modal_login, 'hide');
    expect($scope.modal_login.hide()).toHaveBeenCalled();
  });
});

Both tests now require the open_login_modal function to be called, so I have added it to a beforeEach block. Additionally, make sure to add a spy for the hide function of the modal as well.

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

ensure that angular's ng-if directive sets aside space to display content when triggered by an event

I'm facing an issue with my modal form setup where if a text-field is left blank, a label saying "it is required" is generated below the field, causing the "Proceed" button to move (along with all other elements below it). How can I make sure that DOM ...

Issue with Java Script inheritance in google.maps.OverlayView not functioning as expected

UPDATE: After spending another day working on this, I believe I have identified the issue, although it is not yet confirmed. Once I have verified the solution, I will update this post with an answer. My current understanding is that the problem arises fro ...

Tips on how to ensure a JAVA application opens a webpage in a designated browser

Adding the microsoft-edge prefix to a URL (microsoft-edge:) will open the page in Edge, regardless of the browser being used for running the app. I am wondering if there is an equivalent prefix for Chrome and Firefox? Thank you in advance. ...

I require the ability to retrieve only the data from a UI grid column, specifically based on the column name selected

I need help with my angularjs application that utilizes Ui grid. There is an external dropdown menu located outside of the ui grid, which lists all the column names in the grid. I want to be able to select a specific column name from this dropdown and retr ...

Issue with regex compatibility in Internet Explorer 7 - Regex pattern functioning correctly across all browsers except IE7

My password validation regex ensures that the password is between 6 and 25 characters long, and contains at least one number. var passwordRegEx = /^(?=.*\d)(?=.*[a-zA-Z]).{6,25}$/; if(!#quickRegister_Password').val().test(pass)) { errorMgs += ...

Multiple minute delays are causing issues for the Cron server due to the use of setTimeout()

I have an active 'cron' server that is responsible for executing timed commands scheduled in the future. This server is dedicated solely to this task. On my personal laptop, everything runs smoothly and functions are executed on time. However, ...

Despite having both React and Firebase enabled, the "sign-in provider" feature appears to be disabled

Within my Authentication settings, the Sign-in Method is configured to use Email and Password as enabled. I've set up a handler for form submission that looks like this: createUser(e){ e.preventDefault(); const email = this.createEmail.value ...

React fails to recognize the key prop

When creating a list of TSX elements, I utilized the following code: this.productsModel = this.state.products.map(o => ( <Grid.Column key> However, I encountered a warning from React: Warning: Each child in a list should have ...

Generate a new array of objects by cloning an existing array of objects with placeholder values

I am looking to transform an array of objects into another array of objects in order to generate a graph. Below is the array I am using to determine the position of each object within the new object. let uniqueSkills = ['Using', 'Analyzing ...

Converting JavaScript code for Angular: A step-by-step guide

I have been working on integrating a feature similar to the one demonstrated in this Angular project: https://codepen.io/vincentorback/pen/NGXjda While the code compiles without any issues in VS code, I encountered two errors when attempting to preview it ...

Exploring the potential of Angular $q integration with the dynamic testing duo of Jasmine 2

Looking to perform a test on a promise-based service that functions like this: load : function(){ var deferred = $q.defer(); //Perform miscellaneous asynchronous tasks deferred.resolve(); return deferred.promise; } W ...

Illuminate the current page

I have been working on a website with around 20 pages that all have a side navigation bar. To make it easier to manage, I decided to centralize the links in a JavaScript (JS) file and include it on each HTML page. This way, any changes can be made quickly ...

Utilizing environment variables in a Rails-AngularJS (1.5) project

Currently working on a Rails-AngularJS (1.5) project and encountering difficulties accessing my ENV variables in the JavaScript components such as services and console. I've implemented dotenv, stored my SECRET_KEY in a .env file, and included the fo ...

Display a particular div upon clicking a specific link, while concealing the other divs

As a beginner in the world of jQuery and coding, I'm encountering some difficulties that I need help with. My goal is to have the 'Vlogging' link activated and show 'Details 1' when the page loads. Then, upon clicking on either &a ...

Sending a form using AJAX causes the page to redirect

I have an input type="file" that triggers a form submission upon change. $(document).on("change", "#image-upload", function (e) { $.ajax({ url: '/BlogPost/UploadHomeReport', type: 'POST', data: $('#upload-i ...

Whenever I initiate an AJAX call, my form submits automatically

I have designed a form that sends a list of products to the spring backend. This form consists of two separate buttons: A "Submit" button for submitting the form. A "Fetch available Stock" button for checking stock availability. When the "Fetch available ...

What is the best method for retrieving values from a FlexiGrid?

I'm having trouble finding information on how to retrieve a cell's value from a flexigrid. My goal is to fetch the value of the third column for every checked item (each row has a checkbox). While I have a function that successfully gets the ro ...

Data binding in AngularJS allows for easy synchronization between the model and the view

I've been working on a simple AngularJS application that includes a form with two fields. However, I've run into an issue where I'm unable to read the values entered in these fields from my controller, as I keep getting 'undefined' ...

Implementing user authentication in Rails with Devise and Backbone framework

I am just getting started with backbone.js. Currently, I am working on a rails application utilizing the "backbone-on-rails" gem. After successfully incorporating 3 models and rendering views with backbone, now I am looking to implement authentication usin ...

The specified width and height for a div containing images are not being accepted by Firefox

I am facing an issue with the CSS for a div that contains images and is not displaying any width: .wide{ width:5000px; height:100%; overflow: hidden; z-index: 1; display:none; } Here is the HTML code for the div: <div class="wide ...