Angularjs - Why mock $httpBackend and not $http - angularjs

The Angularjs tutorial shows something using the $http service and then testing that using the $httpBackend mock. What it doesn't explain is why you mock $httpBackend and not just mock the $http service itself? Can anyone shed light of this?

You don't mock $httpBackend. You use it to mock the actual HTTP requests that $http makes. I suppose you probably could just mock $http itself, but $httpBacked provides a lot of functionality for asserting certain requests are made (The expect methods) and for just dummying in a response (The when methods). In short, $httpBacked makes testing code that uses $http much much easier.

Related

Difference between xmlhttp (js) and $http (AngularJS)

In normal JavaScript we use xmlhttp for Ajax. Angular is providing ajax service using $http. Is there anything extra things in $http compare to xmlhttp?
$http in AngularJS cannot be configured to be synchronous while xmlhttp can do either synchronous or asynchronous. In AngularJS world, we use $http because it is the "Angular way" of doing requests.

What is the difference between $http and $resource?

Can I use either for a REST call ? Or is there some minor difference ? I have used both of them in my projects with no side effects,
These are the main differences between $http and $resource:
$http:
$http is for universal purpose. It is an Ajax call.
$http is built into the AngularJS framework.
$http is good for quick retrieval.
$http is injected directly into an AngularJS controller by the developer.
For more details about $http refer: https://docs.angularjs.org/api/ng/service/$http
$resource:
$resource wraps $http to use in RESTful web APIs.
$resource needs to add the module separately.
$resource is good for conditions slightly more complex than $http.
$resource does not allow us to do much with data once it is consumed in the application. It is in the final state when it is delivered to the HTML DOM. The data are the same that the $http method will receive.
For more details about $resource refer: https://docs.angularjs.org/api/ngResource/service/$resource
You can find more answer here and here.

Angular ngmock httpBackend - ignore all but one request?

I am new to writing unit tests, so apologies if this is a dumb question. If I'm trying to test a method in an Angular controller that relies on mock data from a service call, and I want to also mock that service call (ngResource), is there a way to make httpBackend ignore other requests made in my controller on initialization?
I've tried placing my whenGET or expectGET definitions in before blocks, and only instantiating my controller within my test, but I always find that httpBackend is expecting other requests (Error: Unexpected request) when I call flush(). I do not want to write mocks for all other requests, just the one I'm using for this test.
Of course, this may be a stupid idea, as I can also just provide the fake data directly, and not test the service along with the controller's method. I've verified that this works. Maybe the correct answer is that I shouldn't be testing services from within a controller.
FWIW, I've also tried using Sinon fakeServer, and apparently it doesn't even pick up on Angular's XHR implementation (the server never responds).

Mocking an asynchronous web service in Angular unit tests

I'm building an Angular app, and I'm writing unit tests for it. Yay unit tests. I want to mock a particular web service that I'm using (Filepicker.io), which has both a REST API as well as a Javascript API. In my code I use the Javascript API in calls like
filepicker.store(file,
{
options: 'go',
right: 'here'
},
// filepicker's success callback
function(resultObject){
// do stuff with the returned object
}
I know that I could use the $httpBackend provider if I were interacting with Filepicker's REST API, but since my application's code isn't doing that, I'm wondering if/how I could mock an asynchronous API call like this in an Angular unit test.
Do I just override the store method (or the whole filepicker object) in context of my test suite and make it return dummy data of my choosing? That's what they're doing with AngularFire development, with a library that overrides the 'real' Firebase backend service.
Alternately, could I wrap the method in something that uses $httpBackend, so I can use all those handy $httpBackend methods like respond? What's the right strategy here? The first one seems like a simpler and cleaner idea.
Here are some other questions that were similar but ultimately not clear enough for me to fully understand.
AngularJS: unit testing application based on Google Maps API
Unit testing Web Service responses
Mocking Web Services for client layer unit testing
I would first set your SDK as an injectable Service so it can be used more easily by your angular app
myApp.factory('FilePicker',function(){
//likely coming from global namespace
return filepicker;
})
.controller('ctrl',['FilePicker',function(FilePicker){
//use File picker
}];
Now you should be able to inject a mock instead of the real implementation for your tests.
An example with a our controller
describe('ctrl test', function(){
var ctrl;
beforeEach(inject(function($controller){
var mockService={} // here set up a mock
ctrl=$controller('ctrl',{FilePicker:mockService});
}));
});

AngularJs console.log "$q is not defined"

I am getting this error in the console $q is not defined. When I did some research I found some thing like .q library has been deprecated from
http://www.breezejs.com/documentation/breeze-labs/breezeangularqjs
If this is so, then the whole concept of promises is also deprecated,
Promises are not deprecated. In fact they're gaining quite a lot of momentum lately and are included in the next version of JavaScript.
Let's look at what they say:
This breeze.angular.q library has been deprecated. It is superseded by the Breeze Angular Service which more cleanly configures breeze for Angular development.
The Breeze Angular Service tells Breeze to use Angular's $q for promises and to use Angular's $http for ajax calls.
What they say is that breeze uses Angular's own promises for promises rather than its own breeze.angular.q which uses Q promises which are more able but also much heavier than $q promises which Angular uses. This is simply an API change.
Inside Angular code, you can obtain $q using dependency injection - for example with the simple syntax:
myApp.controller("MyCtrl",function($q){
//$q is available here
});
Alternatively, if you want to use it independently you can use service location and obtain $q directly from an injector, but that's rarely the case. (If you want an example - let me know, I'd just rather not include code that's usually indicative of bad practice).
# in your console, try following code
$injector = angular.injector(['ng']);
q = $injector.get('$q');
deferred = q.defer();
# then do whatever you want

Resources