Reputation: 9722
I have the following controller:
export default function($scope, $state, $http) {
$scope.login = () => {
$scope.loginFailed = false;
const postReq: object = {
method: 'POST',
url: `/login`,
data: {},
}
try {
console.log('$scope.login');
const response = await $http(postReq);
console.log('login done');
console.log('$state.go');
$state.go('dashboard');
return true;
} catch(err) {
console.error(err);
$scope.loginFailed = true;
return false;
}
};
}
I'm trying to test this method with Jasmine
it('change state to dashboard', async (done) => {
$httpBackend.expectPOST('/login', undefined).respond(201, { rmId: 123123 });
await $scope.login();
expect($state.current.name).toBe('dashboard');
});
The results of my tests are as follows:
LOG: '$scope.login' PhantomJS 2.1.1 (Mac OS X 0.0.0) $scope.login change state to dashboard FAILED
Now it seems that Jasmine isn't waiting for the $http
call to be completed. (This works fine when I manually test it in a browser)
Is there a better way to correctly test async methods?
Upvotes: 1
Views: 3709
Reputation: 388
you don't need to do the await. you just need to flush the backend mock before expect test your login function must be change like this:
$scope.login = () => {
return new Promise((resolve, reject) => {
$scope.loginFailed = false;
const postReq = {
method: 'POST',
url: `/login`,
data: {},
}
const response = $http(postReq).then(
(success) => {
$state.go('dashboard');
resolve(true);
},
(error) => {
$scope.loginFailed = true;
reject(false);
});
});
};
And your test like :
it('change state to dashboard', async (done) => {
const backendMock = $httpBackend;
backendMock.expectPOST('/login').respond(201, { rmId: 123123 });
$scope.login().then((response) => {
expect($state.current.name).toBe('dashboard');
done();
});
backendMock.flush();
});
Upvotes: 2
Reputation: 2592
You need to use $httpBackend.flush();
before writing your assertions. Add this line before your expect
statement. It should work..
Upvotes: 0