I have an angular controller that needs to be tested. This controller utilizes a service to fetch data from a server, and the service returns ES6 Promises.
function MyController($scope, MyService) {
$scope.doSomething = function () {
MyService.foo().then() {
whatever...;
};
};
};
When writing my Jasmine test, I mock the service which also returns Promises:
var resolve;
var reject;
createPromise = function () {
return new Promise(function (_resolve, _reject) {
resolve = _resolve;
reject = _reject;
});
};
var myServiceMock = {
doSomething: jasmine.createSpy('doSomething').and.callFake(createPromise)
};
beforeEach(module('someApp', function ($provide) {
$provide.value('MyService', myServiceMock);
}));
To check on my controller, I manually trigger the global resolve (or reject) with or without parameters.
it('should call the service', function () {
$scope = $rootScope.$new();
controller = $controller('MyService', { $scope: $scope });
controller.doSomething();
myService.resolve();
expect(whatever...);
});
The issue arises when the resolve call is asynchronous. This means I am testing my expected outcome while the then function is still running.
After attempting to replace Promises with a simple custom object for synchronous resolution in my mocks, I found that re-implementing Promises' specific rules, such as .then(), .catch(), .then() patterns, was cumbersome.
Is there a simpler, synchronous way to test this type of scenario in Jasmine?