I am using AngularJs controller to send data from form to Google Sheet. Using Jasmine I wrote unit-test, which raises the bellow issue:
Error: Unsatisfied requests: POST http://localhost:5000/google-form
at Function.$httpBackend.verifyNoOutstandingExpectation
(.../angular-mocks/angular-mocks.js:1474:13)
After googling and going through some questions in stackowerflow, I decided to post the question as I didn't find a solution for it.
Here is the code for your references:
Angular Controller
/* global $ */
'use strict';
angular.module('myApp')
.controller('QuickMessageCtrl', ['$scope', function ($scope) {
$scope.quickMessageButtonText = 'Send';
$scope.quickMessage = {
name: '',
email: '',
content: '',
};
function setSubmittingIndicators() {
$scope.quickMessageButtonText = '';
$scope.submitting = true;
}
$scope.postQuickMessageToGoogle = _.throttle(function() {
setSubmittingIndicators();
$.ajax({
url: 'https://docs.google.com/forms/d/MyFormKey/formResponse',
data: {
'entry.3' : $scope.quickMessage.name,
'entry.1' : $scope.quickMessage.email,
'entry.0' : $scope.quickMessage.content
},
type: 'POST',
dataType: 'jsonp',
statusCode: {
200: function (){
//show succes message;
}
}
});
}, 500);
}]);
Unit Test Code
'use strict';
describe('Controller: QuickMessageCtrl', function() {
var $httpBackend, $rootScope, $controller, scope, apiUrl;
beforeEach(module('myApp'));
beforeEach(inject(function($injector) {
$httpBackend = $injector.get('$httpBackend');
apiUrl = $injector.get('apiUrl');
$httpBackend.expect(
'POST',
apiUrl + 'google-form',
{'name': 'test', 'email': 'test@test.com', 'content': 'this is content'}
).respond(200);
$rootScope = $injector.get('$rootScope');
scope = $rootScope.$new();
$controller = $injector.get('$controller');
$controller('QuickMessageCtrl', { $scope: scope });
}));
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
describe('Successful form submit', function() {
beforeEach(function() {
scope.quickMessageForm = { $valid: true };
scope.quickMessage.email = 'test@test.com';
scope.quickMessage.name = 'test';
scope.quickMessage.content = 'this is test';
scope.postQuickMessageToGoogle();
});
it('should set submitting indicators on submit', function() {
expect(scope.quickMessageButtonText).toBe('');
});
});
});
Your tests says that the mock http backend should receive a POST at the URL
which, given the error message, is
http://localhost:5000/google-form
.But your controller never sends a POST to that URL. It sends a POST to
https://docs.google.com/forms/d/MyFormKey/formResponse
. And it doesn't do it using angular's $http service, but does it behind its back, using jQuery.As @JB Nizet pointed you are using jQuery instead of angular methods. In fact you should refactor your code a bit.
Its a great practice to keep things separate, like Controller from Service. In your case you are using service inside the controller. I would rather suggest you to create a service and then import that service in your controller. So basically here how the code will look like:
Controller
Service
Unit-test