Angular mocking XHRBackend: how to call mockRespond

I’m adding unit tests to my API and had a bit of bother mocking the API response. However after a lot of console.log and much head scratching I found some voodoo that works.

TWO KEY TAKEAWAYS

1 . Josh Morony’s blog post said the call is

connection.mockRespond ( new Response ( newResponseOptions(...

That didn’t work for me, I had to use

connection.mockRespond ( newResponseOptions ( body: myObjects

2. But that’s not all, my live response (from a MS WebApi) has a ._body property, my mocked response has a .body. So I had to do something like this


if(res['body']){ //works with mocks
//...
}else if(res['_body']){//works in live system
//...
}

I started with this complete example:

git clone https://github.com/ionic-team/ionic-unit-testing-example.git

(The version numbers of the npm packages have to be compatible)

And worked through this blog post (and others!):

Test Driven Development in Ionic 2: Http and Mocks

This would have been a lot easier if I could figure out how to attach a debugger to Karma, no luck with that so far. Anyhow my complete dummy-service.spec.ts (including code for the service) is…

(just as soon as i figure out how to paste code into wordpress…)

import {Injectable} from '@angular/core';
import { Http, HttpModule, XHRBackend, ResponseOptions, Response } from '@angular/http';
import { TestBed, inject } from '@angular/core/testing';
import { MockBackend } from '@angular/http/testing';

@Injectable()
export class DummyService {
  access_token:string;
  constructor(public http:Http){}
  get(){
    console.log('DummyService Test1 F');
    this.http.get('http://localhost').subscribe((res:Response)=>{
      console.log('DummyService Test1 G got ' + JSON.stringify(res));
      if(res['body'] && res['body']['access_token']){
        this.access_token = res['body']['access_token']; //works with mocks
        console.log('loginUser got token from body (we are using a mock)');
      }else if(res['_body'] && JSON.parse(res['_body']) 
&& JSON.parse(res['_body']).access_token){
        this.access_token = JSON.parse(res['_body']).access_token; //works with live system
        console.log('loginUser got token from _body (we are live)');
      }
      console.log('access_token is ' + this.access_token);
    });
  }
}

describe ('DummyService http method',()=>{
  beforeEach(()=>{
    TestBed.configureTestingModule(
      {
        imports:[HttpModule],
        providers:[
          {provide: XHRBackend, useClass:MockBackend},
          DummyService
        ]
      }
    );
  }
  );

  it('should call get and get response',inject([DummyService, XHRBackend],(dummyService, mockBackend)=>{

    console.log('DummyService Test1 A');

    let r1 = "hello"; //works
    let r2 = "{access_token:'SOMETOKEN'}"; //works
    let r3 =  //doesn't work, service gets empty object {}
        new Response(
            new ResponseOptions(
            {
                url:'url',
                status:200,
                body: "here is the info"
            }
            )
        );
    let r4 = JSON.stringify(r3);//doesn't work, service gets empty object {}
    let r5 = new ResponseOptions( //aha THIS is the bunny...
        {
            body: {access_token:'SOMETOKEN'}
        }
        );

    mockBackend.connections.subscribe(
      connection=>{
        console.log('DummyService Test1 D v4 r5');
        connection.mockRespond(r5); 
      }
    );

    console.log('DummyService Test1 B');

    dummyService.get();

    console.log('DummyService Test1 C');
    
    expect(dummyService.access_token).toEqual('SOMETOKEN');

  }));

});

 

Website by WNW Digital