Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing $modal with Jasmine

I have an Angular app with a controller which displays an Angular-Strap modal window during a function call. It functions correctly in Chrome, but I am at a loss getting a valid unit test working.

App module and the FooController:

var app = angular.module("app", ["mgcrea.ngStrap"]);

app.controller("FooController", function($scope, $modal) {
    var fooModal = $modal({
        title: 'Foo',
        content:'Bar',
        show: false,
        html: true,
        backdrop: 'static',
        placement: 'center'});
    
    angular.extend($scope, {
        makeItFoo: function() {
            fooModal.show();
        }
    });
});

Controller spec:

describe('FooController', function () {
    var scope, controller, modal;

    beforeEach(module('app', function ($provide) {
        // Stub out $modal service
        $provide.value('$modal', function () {
            return {
                hide: function () { },
                show: function () { }
            };
        });
    }));

    beforeEach(inject(function ($rootScope, $controller, $injector) {
        //set up a new scope and the controller for the test
        scope = $rootScope.$new();
        controller = $controller('FooController', {$scope: scope});
        modal = $injector.get('$modal');
    }));

    it('should show the modal', function () {
        var modalSpy = spyOn(modal(), 'show');
        
        scope.makeItFoo();
        
        expect(modalSpy).toHaveBeenCalled();
    });
});

Here's a fiddle as well.

I expect my call to makeItFoo() to display the modal, but Jasmine fails the test with the error Expected spy show to have been called. I've also tried setting the show property of the modal to true and not calling show() separately, and I've tried other variants of stubbing the $modal service and injecting it directly into the controller, but it ends up with the same error.

I'm using AngularJS 1.2.14, Angular-Strap 2.0.0, and Jasmine 1.3.1.

like image 673
The DIMM Reaper Avatar asked Oct 27 '14 18:10

The DIMM Reaper


People also ask

How to use Jasmine to test NodeJS unit test framework?

To test Node.js unit test framework, Jasmine must be installed along with Node package manager. Test code is written separately, with ‘spec’ appended to the file name. Without this, the Jasmine test framework is unable to detect files.

What is the use of Jasmine in testing?

Jasmine is the most popular JS library for unit testing web apps. In this tutorial, designed for beginners, we’ll present you with a quick and complete guide to testing with Jasmine. You’ll get introduced to Jasmine, a popular behavior-driven testing framework for JavaScript.

What is the best framework for unit testing JavaScript applications?

Jasmine is a very popular JavaScript behavior-driven development (In BDD, you write tests before writing actual code) framework for unit testing JavaScript applications. It provides utilities that can be used to run automated tests for both synchronous and asynchronous code. Jasmine has many features such as:

How to write specs in Jasmine test framework?

To write specs in Jasmine test framework, user perform the following steps: In the project root directory, run command: npm install jasmine-node –save. The ‘save’ option automatically appends the package to the file and saves the package version. Install the request npm package with command: npm install request –save.


1 Answers

Instead of doing these. Create a mock object for $modal with show and hide methods and set your expectations on them.

describe('FooController', function () {
    var scope, controller, modal;

    beforeEach(module('app'));

    beforeEach(inject(function ($rootScope, $controller) {
        //set up a new scope and the controller for the test
        scope = $rootScope.$new();
        //Create spy object
        modal = jasmine.createSpyObj('modal', ['show', 'hide']);
        //provide modal as dependency to the controller.
        controller = $controller('FooController', {$scope: scope, $modal:modal});

    }));

    it('should show the modal', function () {

        scope.makeItFoo();

        expect(modal.show).toHaveBeenCalled();
    });
});
like image 110
PSL Avatar answered Oct 23 '22 09:10

PSL