2017-02-24 100 views
0

我有一個非常簡單的service.show()基本上與一些配置調用$ uibModal並返回該模式的實例

function modalService($uibModal) { 
    return { 
    show(message) { 
     return $uibModal.open({ 
     bindToController: true, 
     controllerAs: '$ctrl', 
     template: "<div id='message'>{{$ctrl.message}}</div>", 
     controller: [function() { 
      this.message = message; 
     }] 
     }); 
    } 
    } 
} 

我想編寫一個測試來驗證實際的模態,以及是否包含預期的消息。類似這樣的:

it('should show correct message', (done) => { 
    modal = modalService.show('hello'); 
    modal.rendered.then(()=> { 
     expect($('#message').text()).toBe('hello'); 
     done() 
    }); 
    }); 

但是rendered承諾永遠不會解決。我可以做一些解決方法,比如將expect換成$timeout並做$timeout.flush(),但不知道這是否正確,甚至這樣我仍然無法清理(afterEach)關閉模式並準備測試另一條消息。

回答

1

正確的方法是打開模式窗口查看消息並關閉它,並且當引導程序使用ngAnimate作爲動畫時,我們必須包含ngAnimateMock模塊以刷新未決動畫。

檢查溶液中的下面的代碼:

var myApp = angular.module('myApp', ['ngAnimate', 'ui.bootstrap']); 
 

 
myApp.factory('modalService', ['$uibModal', function($uibModal) { 
 
    return { 
 
    show(message) { 
 
     return $uibModal.open({ 
 
     bindToController: true, 
 
     controllerAs: '$ctrl', 
 
     template: '<div id="message">{{$ctrl.message}}</div>', 
 
     controller: [function() { 
 
      this.message = message; 
 
     }] 
 
     }); 
 
    } 
 
    } 
 
}]); 
 

 
describe('modalService service', function() { 
 
    describe('modalService', function() { 
 
    var modalService; 
 
    var $rootScope; 
 
    var $animate; 
 

 
    beforeEach(function() { 
 
     module('ngAnimateMock') 
 
     module('uib/template/modal/window.html') 
 
     module('myApp'); 
 
    }); 
 

 
    beforeEach(inject(function(_$rootScope_, _modalService_, _$animate_) { 
 
     $rootScope = _$rootScope_; 
 
     modalService = _modalService_; 
 
     $animate = _$animate_; 
 
    })); 
 

 
    it('should open the dialog with the correct message',() => { 
 
     var modal = modalService.show('hello'); 
 

 
     $rootScope.$digest(); 
 
     // Finish the animation. 
 
     $animate.flush(); 
 

 
     expect($('#message').text()).toEqual('hello'); 
 

 
     // Close the dialog. 
 
     modal.close(); 
 

 
     $rootScope.$digest(); 
 
     // Finish the animation. 
 
     $animate.flush(); 
 
    }); 
 

 
    it('again should show the correct message',() => { 
 
     var modal = modalService.show('new message'); 
 

 
     $rootScope.$digest(); 
 
     // Finish the animation. 
 
     $animate.flush(); 
 

 
     expect($('#message').text()).toEqual('new message'); 
 

 
     // Close the dialog. 
 
     modal.close(); 
 

 
     $rootScope.$digest(); 
 
     // Finish the animation. 
 
     $animate.flush(); 
 
    }); 
 
    }); 
 
});
<body> 
 
    <!-- because we are testing our controller and not running we don't need a controller or even a module --> 
 
    <!-- so there is no ng-app or ng-controller in the markup --> 
 

 
    <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.css"> 
 

 
    <!-- the order that these files load is critical, think twice before changing --> 
 
    <script src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine.js"></script> 
 
    <script src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/jasmine-html.js"></script> 
 
    <script src="//cdnjs.cloudflare.com/ajax/libs/jasmine/2.0.0/boot.js"></script> 
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 
 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script> 
 
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-animate.js"></script> 
 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-mocks.js"></script> 
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap-tpls.min.js"></script> 
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap.min.js"></script> 
 

 
    <h2>Finished jasmine-unit-test</h2> 
 

 
</body>

+0

第一測試通過,但第二個失敗,消息'應爲「新messagehello」等於「新message'.' 'modal.close()'不會將模式從dom中刪除。你有線索爲什麼會發生? – jonasnas

+0

,爲什麼我需要模塊('uib/template/modal/window.html')? – jonasnas

+0

我提供的代碼片段,都是測試通過。你可以提供codepen/jsfiddle等,以便我可以查看該內容。關於你的其他問題,你需要包含'module('uib/template/modal/window.html')',因爲當你在內部調用'$ uibModal.open()'調用時,它會獲取模板'window.html' 。 – Gaurav