I am solving this by just creating mock modal
and modalInstance
objects and verifying that they have been called by my controller code. Since modal
and modalInstance
are part of a third party library, it's not our responsibility to test that they work properly - rather, it's our responsibility to test that our code which calls the library is working ok.
Using your example:
describe('Controller: modalCtrl', function () {
beforeEach(module('myApp'));
var Ctrl;
var scope;
var modalInstance;
// Initialize the controller and a mock scope
beforeEach(inject(
function ($controller, $rootScope) { // Don't bother injecting a 'real' modal
scope = $rootScope.$new();
modalInstance = { // Create a mock object using spies
close: jasmine.createSpy('modalInstance.close'),
dismiss: jasmine.createSpy('modalInstance.dismiss'),
result: {
then: jasmine.createSpy('modalInstance.result.then')
}
};
Ctrl = $controller('modalCtrl', {
$scope: scope,
$modalInstance: modalInstance,
itemArray: function () { return ['a', 'b', 'c']; }
});
})
);
describe('Initial state', function () {
it('should instantiate the controller properly', function () {
expect(Ctrl).not.toBeUndefined();
});
it('should close the modal with result "true" when accepted', function () {
scope.accept();
expect(modalInstance.close).toHaveBeenCalledWith(true);
});
it('should close the modal with result "false" when rejected', function () {
scope.reject();
expect(modalInstance.close).toHaveBeenCalledWith(false);
});
});
});
This way, we don't really need any dependency on the Angular-UI objects and our unit tests are nice and isolated.