Reputation: 128327
Say I have a controller which upon initialization makes 3 different requests with the $http service. I would like to write three different tests, each of which only cares about one of the requests.
For example, suppose the controller looks like:
app.controller('ExampleCtrl', function($scope, $http) {
$http.get('/foo', /* ... */);
$http.get('/bar', /* ... */);
$http.get('/baz', /* ... */);
});
Then I would like to write tests like:
describe('ExampleCtrl', function() {
var http;
beforeEach(inject(function($httpBackend, $controller) {
http = $httpBackend;
$controller('ExampleCtrl');
}));
it('loads "/foo" and does whatever', function() {
http.expectGET('/foo').repond(/* ... */);
http.flush();
expect(/* ... */);
});
it('loads "/bar" and does whatever else', function() {
/* etc. */
});
});
This doesn't appear to work because, from what I can see, when I call flush()
Angular assumes I must have specified all of the requests that should have been made. So for instance if I only specified expectGET('/foo')
then Angular will complain that there were unexpected requests to '/bar'
and '/baz'
.
Is there a way to do what I'm trying to do here? Am I approaching this problem from the wrong angle?
One approach, I realize, is that I could probably put all of the expectGET
s in a beforeEach
and only test the results in test cases. But that seems like an unfortunate workaround, having to scatter my expectations across multiple places.
Upvotes: 1
Views: 211
Reputation: 19249
I think http.expectGET('/foo').repond(/* ... */);
can be viewed as setup code. After all your are configuring a mock by telling it how to respond. So I'd put it in beforeEach
and wouldn't see that as a workaroud.
Another option would be to mock $http
with your own spy/mock using $provide
:
beforeEach(module('plunker', function ($provide) {
$provide.value('$http', {
get : function(a){
this.calls = this.calls || [];
this.calls.push(a);
}
});
}));
And then you can check the calls the way you want to. See this plnkr to get you started.
Upvotes: 2