2016-09-09 5 views
9

그래서 내 angular2 구성 요소 & 서비스를 테스트하고 있습니다.MockBackend를 Angular2로 사용하여 Http post, put, delete에 대한 단위 테스트를 수행하는 방법은 무엇입니까?

은 지금까지 나는 다음과 같이 서비스에 GET 요청을 조롱하기위한 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'); 
    } 
} 

을 , 나는 제대로 작동하고 있으므로 내 service.spec.ts 파일에서 getAllPages() & getPageById() 메소드를 올바르게 구현했습니다.

savePage() , updatePage() , deletePage() 메서드에 대한 테스트 사례를 구현하는 방법을 알고 싶습니다.

입력 사항이 있습니까?

미리 감사드립니다.

답변

3

메서드의 내부를 살펴보고 그 작업 내용을 확인해야합니다. 이것은 예상 된 동작을 테스트하는 방법입니다.

  • Content-Type 헤더를 설정하고 있습니다. 따라서 이것이 필수 사항이므로이 동작을 테스트해야합니다. 당신은 당신은 URL을 설정하고있는 MockConnection#request

    backend.connections.subscribe((conn: MockConnection) => { 
        let contentType = conn.request.headers.get('Content-Type'); 
        expect(contentType).not.toBeNull(); 
        expect(contentType).toEqual('application/json'); 
    }); 
    
  • 에서 헤더를 얻을 수있다, 그래서 이것은 요구 사항입니다. 이것은 테스트되어야합니다. 당신은 이미

    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(); 
    

    나는 catch 방법은 귀하의 HTTP 요청에 호출되는 경우합니다 (MockConnection 사용)를 찾을 수 없습니다, 그건입니다. conn.mockError(new Error())을 시도했지만 작동하지 않았습니다. 연결 안에 오류가 발생했습니다. 작동하지 않았습니다. 어쩌면 당신은 그것을 알아낼 수 있습니다.