[Angular] Angular 單元測試起手式
建立 spy object
在這邊我有一個 VoterService ,且有一個 deleteVoter 的方法,可以執行刪除的動作,而為了能發 Http 到 Server,Angular 都是用 HTTP 這類別來發送 http request,所以我建構式注入了 HTTP,而我在單元測試的時候,也就可以注入假的 HTTP 物件。
- ts
1 | () |
使用 createSpyObj 建立假的 HTTP 物件。
參數說明:
- mockHttp : base name, 可隨意輸入
- [‘delete’] : Spy 物件有 delete 這個方法
Spy - ts
1
let mockHttp = jasmine.createSpyObj('mockHttp', ['delete']);
撰寫完整的單元測試,而這裡我們要確切的指定 delete 方法回傳 Observable
物件,否則 .catch
與 .subscribe
則會錯誤。
mockHttp.delete.and.returnValue(Observable.of(false));
: Spy 物件的 delete 方法回傳Observable
, 因為要測試的 deleteVoter 方法,並沒有在 subscribe 裡面執行任何程式碼,所以使用Observable.of(false)
建立一個Observable
物件。unit test - ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25describe('VoterService', () => {
let voterService: VoterService,
mockHttp;
beforeEach(() => {
mockHttp = jasmine.createSpyObj('mockHttp', ['delete'])
voterService = new VoterService(mockHttp);
});
describe('deleteVoter', () => {
it('should remove the session from the list of sessions', () => {
var session = { id: 6, voters: ["joe", "john"]};
mockHttp.delete.and.returnValue(Observable.of(false));
voterService.deleteVoter2(<ISession>session, "joe");
expect(session.voters.length).toBe(1);
expect(session.voters[0]).toBe("john");
})
})
})
驗證傳入參數
新增另一個 addVoter 的方法,執行 http.post 發送資料到 http://localhost:3000/api/sessions/voters/joe
API 位址1
2
3
4
5
6
7
8
9addVoter(session: ISession, voterName: string) {
session.voters.push(voterName);
let headers = new Headers({ 'Content-Type': 'application/json'});
let options = new RequestOptions({headers: headers});
let url = `${environment.host}/api/sessions/voters/${voterName}`;
this.http.post(url, JSON.stringify({}), options).catch(this.handleError).subscribe();
}
使用 toHaveBeenCalledWith 驗證 post 傳入的網址是否如預期,以及使用 jasmine.any 驗證傳入的物件型別是否如預期。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23describe('VoterService', () => {
let voterService: VoterService,
mockHttp;
beforeEach(() => {
mockHttp = jasmine.createSpyObj('mockHttp', ['delete', 'post'])
voterService = new VoterService(mockHttp);
});
describe('addVoter', () => {
it('should call http.post with the right URL', () => {
var session = { id: 6, voters: ["john"]};
mockHttp.post.and.returnValue(Observable.of(false));
voterService.addVoter(<ISession>session, "joe");
expect(mockHttp.post).toHaveBeenCalledWith('http://localhost:3000/api/sessions/voters/joe', "{}", jasmine.any(RequestOptions));
})
})
})