Unit testing $ modal with Jasmine

I have an Angular application with a controller that displays an Angular-Strap modal window during a function call. It functions correctly in Chrome, but I find it difficult to get a valid unit test working.

Application module and 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 Specification:

 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(); }); }); 

There is also a violin.

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

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

+6
source share
2 answers

Instead of this. Create a mock for $modal using the 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(); }); }); 
+7
source

The modal show is asynchronous. I updated my script at http://jsfiddle.net/jwom7ns2/1/ .

Change the following part:

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

The timeout browser expects a digest to happen when a modal show occurs.

+1
source

Source: https://habr.com/ru/post/977291/


All Articles