Reputation: 3580
I have a very simple service.show() which basically calls $uibModal with some configuration and returns the modal instance
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;
}]
});
}
}
}
I would like to write a test to validate actual modal and if it contains expected message. Something like this:
it('should show correct message', (done) => {
modal = modalService.show('hello');
modal.rendered.then(()=> {
expect($('#message').text()).toBe('hello');
done()
});
});
but rendered
promise is never resolved. I can do some workaround like wrapping expect
into $timeout
and do $timeout.flush()
but not sure if this is correct way and even in this way I still can't do a cleanup (afterEach
) to close the modal and be ready to test another message.
Upvotes: 0
Views: 808
Reputation: 1233
The correct way will be to open the modal window look for the message and close it and as bootstrap is using ngAnimate
for the animation we will have to include ngAnimateMock
module to flush the pending animation.
Check the below code for the solution:
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>
Upvotes: 1