AngularJS unit testing: $httpBackend.when dynamic responses

angularjs

I'm playing with AngularJS unit testing when developing Feed (RSS) application. The Feed can fetch remote rss data parse it and save parsed items. For testing rss fetching I use $httpBackend mock:

beforeEach(inject(function (_$httpBackend_, _feedMock_, _mockConfig_) {
    _$httpBackend_.when('GET', _mockConfig_.FEED_URL).respond(_feedMock_);
}));

and then below

$httpBackend.expectGET(mockConfig.FEED_URL);
feed.fetch();
$httpBackend.flush();

it works fine.

But I need to make the Feed can actualize it's state by fetching updated rss data and appending new items. So, the Feed make the same request, but got new updated data. I'm trying to recreate server definition by something like this:

$httpBackend.when('GET', _mockConfig_.FEED_URL).respond(feedMockUpdated);

and then make the same operation with expect and flush, but $httpBackend response with old data (feedMock), not new (feedMockUpdated). How can I make $httpBackend to response with the different data on the same request?

Best Solution

You can set up respond with a function, not just a static data set.

From the docs:

http://docs.angularjs.org/api/ngMock.$httpBackend

respond – {function([status,] data[, headers])|function(function(method, url, data, headers)} – The respond method takes a set of static data to be returned or a function that can return an array containing response status (number), response data (string) and response headers (Object).

So as I understand in your case, you want to have the same endpoint return different data on later calls, you can try something like the following. This is just implementing a simple counter that will switch the data on a subsequent call.

var rssCalled = 0;

$httpBackend.when('GET', _mockConfig_.FEED_URL).respond(function(method, url, data, headers){
    if(rssCalled === 0) {
        rssCalled++;
        return [200, feedMock, {}];
    } else {
       return [200, feedMockUpdated, {}];
    }
});