Как выполнить модульный тест для публикации, размещения, удаления Http с помощью MockBackend в Angular2?

Итак, я тестирую свои компоненты и сервисы angular2.

До сих пор я использовал mockBackend для имитации запроса на получение в службе, как показано ниже:

/* tslint:disable:no-unused-variable */

import { MockBackend } from '@angular/http/testing';
import { Http, ConnectionBackend, BaseRequestOptions, Response, ResponseOptions } from '@angular/http';
import { PagesService } from './pages.service';
import { tick, fakeAsync } from '@angular/core/testing/fake_async';
import { inject, TestBed } from '@angular/core/testing/test_bed';
import {GlobalService} from './../../shared/global.service';

describe('PagesService', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        {
          provide: Http, useFactory: (backend: ConnectionBackend, defaultOptions: BaseRequestOptions) => {
            return new Http(backend, defaultOptions);
          }, deps: [MockBackend, BaseRequestOptions]
        },
        { provide: PagesService, useClass: PagesService },
        { provide: GlobalService, useClass: GlobalService },
        { provide: MockBackend, useClass: MockBackend },
        { provide: BaseRequestOptions, useClass: BaseRequestOptions }
      ]
    });
  });

  //should retrive all search results
  it('should retrieve all search results',
    inject([PagesService, MockBackend], fakeAsync((pagesService: PagesService, mockBackend: MockBackend) => {
      let res: Response;
      mockBackend.connections.subscribe(c => {
        expect(c.request.url).toBe('http://localhost:3200/pm/pages/');
        let response = new ResponseOptions({
          body: '[{"name": "Rapid"}, {"name": "NGBC"}]'});
          c.mockRespond(new Response(response));
        });
        pagesService.getAllpages().subscribe((response) => {
           res = response;              
        });
        tick();
        expect(res[0].name).toBe('Rapid');
     }))
  );
 it('should fetch by Page id',
  inject([PagesService, MockBackend], fakeAsync((pagesService: PagesService, mockBackend: MockBackend) => {
    let res;
    mockBackend.connections.subscribe(c => {
      let page_id:string='2';
      expect(c.request.url).toBe('http://localhost:3200/pm/pages/'+page_id);
      let response = new ResponseOptions({body: '[{"id": 1, "name": "Rapid"}, {"id": 2, "name": "NGBC"}]'});
      c.mockRespond(new Response(response));
    });
    pagesService.getPageById('2').subscribe((response) => {
      res = response;
   });
   tick();
   expect(res[1].name).toBe('NGBC');
   }))
 ); 
});

Если вы хотите увидеть мой service.ts, как показано ниже:

export class PagesService {
    private headers = new Headers();
    public baseUrl:string;
    constructor(private http: Http,private _globalService:GlobalService) {
        this.baseUrl=this._globalService.baseUrl;
    }
    getAllpages() {
        return this.http.get(this.baseUrl + '/pm/pages/')
            .map((res: Response) => res.json()).catch(this.handleError);
    }

    getPageById(page_id: string) {
        return this.http.get(this.baseUrl + '/pm/pages/' + page_id)
            .map((res: Response) => res.json()).catch(this.handleError);
    }

    savePage(page: Object) {
        this.headers=new Headers();
        this.headers.append('Content-Type', 'application/json');
        let url = this.baseUrl+'/pm/pages/';
        let data={};
        data["data"]=page;
        return this.http.post(url, JSON.stringify(data),{headers: this.headers})
           .map((res: Response) => res.json()).catch(this.handleError);
    }

    updatePage(page: any) {
        this.headers=new Headers();
        this.headers.append('Content-Type', 'application/json');
        let url = this.baseUrl+'/pm/pages/'+page._id;
        let data={};
        data["data"]=page;
        return this.http.put(url, JSON.stringify(data),{headers: this.headers})
            .map((res: Response) => res).catch(this.handleError);
    }

    deletePage(page_id: string) {
         this.headers=new Headers();
         this.headers.append('Content-Type', 'application/json');
         let url = this.baseUrl+'/pm/pages/';
         return this.http.delete(url + page_id,{headers: this.headers,body: ''})
             .map((res: Response) => res).catch(this.handleError);
    }

    mergePage(page: Object) {
        return this.http.post(this.baseUrl + '/pm/pages/',JSON.stringify(page))
            .map((res: Response) => res.json()).catch(this.handleError);
    }

    handleError(error: any) {
        console.error(error);
        return Observable.throw(error.json().error || 'Server error');
    }
}

из приведенного выше сервиса я правильно реализовал методы getAllPages() и getPageById() в моем файле service.spec.ts, поскольку они работают нормально.

Я хочу знать, как реализовать тестовые примеры для методов savePage() , updatePage() , deletePage().

Любые входы?

Заранее спасибо.


person Bhushan Gadekar    schedule 09.09.2016    source источник


Ответы (1)


Вам нужно изучить внутренности методов и посмотреть, что они делают. Вот как вы проверяете его ожидаемое поведение.

  • Вы устанавливаете заголовок Content-Type. Так что это требование, и вы должны проверить это поведение. Вы можете получить заголовки из MockConnection#request

    backend.connections.subscribe((conn: MockConnection) => {
      let contentType = conn.request.headers.get('Content-Type');
      expect(contentType).not.toBeNull();
      expect(contentType).toEqual('application/json');
    });
    
  • Вы устанавливаете URL-адрес, так что это требование. Это должно быть проверено. Ты уже

    expect(conn.request.url).toBe('...');
    
  • Вы отправляете данные. Так что это требование. Вы должны проверить, чтобы убедиться, что данные находятся в требуемом формате/структуре.

    let body = conn.request.json();
    expect(body.data).toEqual('page');
    

Это для части запроса.

Что касается части ответа, вы должны проверить, что ваша служба делает с этим ответом.

  • Если вы получаете тело, вы должны проверить его так же, как вы сделали это с запросом GET.

  • Вы также обрабатываете ошибку с помощью обратного вызова ошибки. Вам не нужно проверять, что здесь делает обратный вызов. Это должно быть его собственное испытание. Все, что мы хотим проверить, это то, что дескриптор ошибки вызывается из тестируемого метода. Для этого мы должны использовать шпиона. Мы можем подсмотреть в функции handleError, а затем проверить, что она была вызвана.

    spyOn(service, 'handleError').and.callFake(() => {});
    // make call
    tick();
    expect(service.handleError).toHaveBeenCalled();
    

    Я не смог найти случай (используя MockConnection), когда метод catch вызывается по вашему Http-запросу, поэтому я не опубликовал пример. Пробовал conn.mockError(new Error()), не помогло. Я пытался выдать ошибку внутри соединения, это не сработало. Может быть, вы можете понять это.

person Paul Samsotha    schedule 14.09.2016