The following test keeps failing and I can't figure out why? I am trying to figure out how to test defereds/promises with Jasmine.
Error
Expected undefined to be 'Resolved Data'.
Test
describe('Queued Repository', function () {
var ctrl,
rootScope,
scope,
service;
beforeEach(function () {
module('testApp');
inject(function ($rootScope, $controller, TestSrvc) {
rootScope = $rootScope;
scope = $rootScope.$new();
service = TestSrvc;
});
});
afterEach(inject(function ($rootScope) {
$rootScope.$apply();
}));
it('test something', function () {
expect(service.calculate(1, 5)).toBe(6);
});
it('resolves promises', function () {
var result;
service.getPromise().then(function (data) {
result = data;
});
rootScope.$apply();
expect(result).toBe('Resolved Data');
});
});
Service
var app = angular.module('testApp', []);
app.service('TestSrvc', ['$q', '$timeout', '$http', function ($q, $timeout, $http) {
return {
getPromise: function () {
var d = $q.defer();
$timeout(function () {
d.resolve('Defered Result');
}, 5000);
return d.promise;
},
getSomething: function () {
return "Test";
},
calculate: function (x, y) {
return x + y;
}
}
}]);
describe('test promise with jasmine', function() { it('expects a rejected promise', function() { var promise = getRejectedPromise(); // return expect(promise). toBe('rejected'); return expect(promise. inspect(). state).
If an operation is asynchronous just because it relies on setTimeout or other time-based behavior, a good way to test it is to use Jasmine's mock clock to make it run synchronously. This type of test can be easier to write and will run faster than an asynchronous test that actually waits for time to pass.
Create a Mock API with Jasminejson file in your root directory. If not, you can set it up with this command: npm init -y . Your test should pass! Try changing the value of a to false, and running it again to see what it looks like when a test fails.
Try calling $timeout.flush()
before expect(result).toBe('Resolved Data');
.
In your example, you will need to call both $timeout.flush()
AND $rootScope.$apply()
.
Explanation: $timeout.flush()
will force your $timeout
in the service to run immediately. Your service will then call 'resolve
' - but the promise.then()
will not be called until the subsequent digest cycle; therefore you will need to call $rootScope.$apply()
to propagate any 'resolves' and 'watches' - which will occur synchronously.
NOTE:
In Jasmine, ensure that your promise.then()
function appears BEFORE
your call to $rootScope.$apply
otherwise it will not fire the promise.then()
function. (I haven't figured out why this is the case in Jasmine.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With