6

У меня есть приложение с угловым выражением с контроллером, в котором во время вызова функции отображается модальное окно Angular-Strap. Он корректно функционирует в Chrome, но я затрудняюсь с получением действительного модульного теста.

App модуль и 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(); 
     } 
    }); 
}); 

контроллер Спецификация:

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.

Я ожидаю, что мой призыв к makeItFoo(), чтобы отобразить модальный, но Жасмин не может тест с ошибкой Expected spy show to have been called. Я также пробовал установить свойство show модального на true и не звонил show() отдельно, и я пробовал другие варианты обрезания $ модального сервиса и впрыскивания его непосредственно в контроллер, но он заканчивается той же ошибкой.

Я использую AngularJS 1.2.14, Angular-Strap 2.0.0 и Jasmine 1.3.1.

ответ

7

Вместо этого. Создайте макет объекта для $modal с помощью методов show и hide и установите на них свои ожидания.

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

Я был в середине своего ответа, когда вы разместили его, вы прибивали его;) – maurycy

+0

@maurycy haha ​​иногда бывает и для меня .. :) – PSL

+0

@PSL, спасибо! Я пытался понять правильный способ издеваться над модальным, и это похоже на это. Однако, обновив мою скрипку, как вы описали, тест все еще терпит неудачу. В частности, ошибка теперь читает 'Argument 'FooController' не является функцией, получившей undefined'; обновленная скрипка [здесь] (http://jsfiddle.net/dimmreaper/jwom7ns2/3/). –

1

Модальное шоу асинхронное. Я обновил вашу скрипку по адресу http://jsfiddle.net/jwom7ns2/1/.

Изменить следующую часть:

it('should show the modal', function (done) { 
    var modalSpy = spyOn(modal(), 'show'); 

    scope.makeItFoo(); 

    setTimeout(function() { 
     expect(modalSpy).toHaveBeenCalled(); 
     done(); 
    }); 

}); 

тайм-аут оболочка ждет дайджеста произойти, когда происходит модальное шоу.

+0

Я собирался прокомментировать, прежде чем вы пересмотрели свой ответ о том, почему «scope. $ Apply» ?. Но я думаю, что это также, вероятно, является чрезмерным ИМХО, потому что OP уже создал макет obj, а затем установил шпиона. Вместо этого все можно сделать сразу, создав макет с использованием жасмина. Также вам не нужно делать '$ injector.get ('$ modal')' вместо '$ modal' может быть непосредственно введено. – PSL

+1

Спасибо, это определенно похоже на жизнеспособное решение. Я собираюсь сделать первый шаг к методу @ PSL издевательства над $ modal, так как я бы предпочел не заниматься тайм-аутом явно. Если у меня есть проблемы, я буду учитывать ваше решение. Благодаря! –

Смежные вопросы