David Votrubec
David Votrubec

Reputation: 4156

How to override mocked response of $httpBackend in Angular?

Is is possible to override or re-define mocked response in mocked $httpBackend?

I have test like this:

beforeEach(inject(function ($rootScope, $controller, _$httpBackend_) {
  $httpBackend = _$httpBackend_;

  //Fake Backend
  $httpBackend.when('GET', '/myUrl').respond({}); //Empty data from server
  ...some more fake url responses...     
 }

This is fine for most cases but I have few tests where I need to return something different for the same URL. But it seems that once the when().respond() is defined I can not change it afterwards in code like this:

Different response in a single specific test:

it('should work', inject(function($controller){
  $httpBackend.when('GET', '/myUrl').respond({'some':'very different value with long text'})

  //Create controller

  //Call the url

  //expect that {'some':'very different value with long text'} is returned
  //but instead I get the response defined in beforeEach
}));

How do I do that? My code is now untestable :(

Upvotes: 27

Views: 10682

Answers (5)

Srikanth Babu K
Srikanth Babu K

Reputation: 101

One other option is:

You can use $httpBackend.expect().respond() instead of $httpBackend.when().respond()

Using expect(), you can push the same url twice and get different responses in the same order you pushed them.

Upvotes: 9

Zain Rizvi
Zain Rizvi

Reputation: 24636

In your test use .expect() instead of .when()

var myUrlResult = {};

beforeEach(function() {
  $httpBackend.when('GET', '/myUrl')
      .respond([200, myUrlResult, {}]);
});


it("overrides the GET" function() {
  $httpBackend.expect("GET", '/myUrl')
      .respond([something else]);
  // Your test code here.
});

Upvotes: 6

trans1t
trans1t

Reputation: 431

The docs seem to suggest this style:

var myGet;
beforeEach(inject(function ($rootScope, $controller, _$httpBackend_) {
    $httpBackend = $_httpBackend_;
    myGet = $httpBackend.whenGET('/myUrl');
    myGet.respond({});
});

...

it('should work', function() {
    myGet.respond({foo: 'bar'});
    $httpBackend.flush();
    //now your response to '/myUrl' is {foo: 'bar'}
});

Upvotes: 28

John Tjanaka
John Tjanaka

Reputation: 129

Use a function in the respond, for example:

var myUrlResult = {};

beforeEach(function() {
  $httpBackend.when('GET', '/myUrl').respond(function() {
    return [200, myUrlResult, {}];
  });
});

// Your test code here.

describe('another test', function() {
  beforeEach(function() {
    myUrlResult = {'some':'very different value'};
  });

  // A different test here.

});

Upvotes: 12

psytau
psytau

Reputation: 142

You could reset 'when' responses in the same function where you conduct the tests.

it('should work', inject(function($controller){
    $httpBackend.when('GET', '/myUrl').respond({'some':'value'})
    // create the controller
    // call the url
    $httpBackend.flush();
    expect(data.some).toEqual('value');
});
it('should also work', inject(function($controller){
    $httpBackend.when('GET', '/myUrl').respond({'some':'very different value'})
    // create the controller
    // call the url
    $httpBackend.flush();
    expect(data.some).toEqual('very different value');
});

See an example in this plunker: http://plnkr.co/edit/7oFQvQLIQFGAG1AEU1MU?p=preview

Upvotes: 0

Related Questions