![](/img/trans.png)
[英]How to mock “localforage” in angular jasmine unit test cases
[英]How mock object work in Angular jasmine unit test
我正在學習單元測試和Angular,所以我兩個都是初學者。 我已經提到了幾個關於單元測試http的角度的教程和文章。
我無法理解httpMock使用HttpTestingController做了什么。 我們稱實際服務的功能然后我們稱之為模擬? 什么是潛在的過程? 請參閱一些文章以獲得更好的理解。
提前致謝。
編輯:這是我堅持使用httpMock的問題 。
我們以我的一個文件為例,好嗎?
import { SimpleConfiguration } from '../../../../../model/SimpleConfiguration';
import { SessionService } from '../../../session/session.service';
import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { ConfigurationService } from './configuration.service';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
describe('ConfigurationService', () => {
let httpMock: HttpTestingController;
let service: ConfigurationService;
const createFakeFile = (fileName: string = 'fileName'): File => {
const blob = new Blob([''], { type: 'text/html' });
blob['lastModifiedDate'] = '';
blob['name'] = fileName;
return <File>blob;
};
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule,
HttpClientTestingModule
],
providers: [ConfigurationService, SessionService]
});
httpMock = TestBed.get(HttpTestingController);
service = TestBed.get(ConfigurationService);
});
it('should be created', done => {
expect(service).toBeTruthy();
done();
});
it('getConfigurations should GET on postes-sources/:postID/configuration', (done) => {
service.getConfigurations(0).subscribe(res => done());
const successRequest = httpMock.expectOne(service.URL + 'postes-sources/0/configurations');
expect(successRequest.request.method).toEqual('GET');
successRequest.flush(null);
httpMock.verify();
});
it('uploadFile should POST on postes-sources/:postID/configuration', (done) => {
service.uploadFile(0, createFakeFile(), new SimpleConfiguration()).subscribe(res => done());
const successRequest = httpMock.expectOne(service.URL + 'postes-sources/0/configurations');
expect(successRequest.request.method).toEqual('POST');
successRequest.flush(null);
httpMock.verify();
});
it('updateComment should POST on postes-sources/:postID/configurations/:confID', (done) => {
service.updateConfiguration(0, 0, new SimpleConfiguration()).subscribe(res => done());
const successRequest = httpMock.expectOne(service.URL + 'postes-sources/0/configurations/0');
expect(successRequest.request.method).toEqual('POST');
successRequest.flush(null);
httpMock.verify();
});
it('getComponentInformations should GET on postes-sources/:postID/tranches/:trancheID/parametres', (done) => {
service.getComponentInformations(0, 0).subscribe(res => done());
const successRequest = httpMock.expectOne(service.URL + 'postes-sources/0/tranches/0/parametres');
expect(successRequest.request.method).toEqual('GET');
successRequest.flush(null);
httpMock.verify();
});
});
讓我一步一步向你詳細解釋。
我們首先describe
我們的測試。 它允許我們對測試進行分組。 在這種情況下,我們按功能對測試進行分組,我們的功能是名為ConfigurationService的服務。 然后我們提供一個回調函數:這是Jasmine運行測試的函數。
接下來,我們聲明我們的變量。 在這里,我們聲明了2個變量和一個函數: httpMock
, service
和createFakeFile()
。 這些變量在整個測試組中都會有所幫助,因此我們將它們聲明為頂級。
然后是beforeEach
:在每次測試之前,這個函數都會運行,做一些事情。 在這一步中 ,它將創建一個TestBed :這是一些樣板代碼,它將創建某種Angular模塊,以允許您的測試運行,就像您的功能在真正的Angular應用程序中一樣。
在這個測試床中,您需要聲明您的依賴項 :因為我正在測試HTTP服務,所以我必須導入HTTP測試模塊,並且因為我的測試使用路由,所以我還必須導入路由器測試模塊。 我也需要導入正在測試的服務,並導入一個SessionService
因為我也在我的服務中使用它。
之后,我通過TestBed.get
獲取這些依賴項的服務實例 :這將允許我監視它們的屬性,並查看它們的值以及它們是否被調用。 這也允許我調用我想測試的函數。
有第一次測試。 第一個非常簡單,默認情況下實現:我測試服務是否正確創建。 如果沒有,這意味着你缺乏依賴,或者你嘲笑你的依賴錯誤。 expect(service).toBeTruthy()
是真正的測試: 對於expect,jasmine期望 (duh) 服務是truhty (即它不應該等於undefined或null)。
下一個測試是一個真正的測試:在這個測試期間,我希望我的函數用某個動詞調用某個端點。
我首先說,一旦打電話,我必須結束測試。 這是通過調用done
,這是上面給出的回調。
然后,我模擬了一個HTTP調用:這意味着我讓Angular相信我正在進行HTTP調用,但實際上我假裝。 但在它看來,它就像是在制造一個真實的:這就是模擬: 模擬行為或價值 。 如您所見,我在特定端點上模擬HTTP調用,並且我期望一個特定的HTTP謂詞。
最后,如果我的函數getConfigurations
GETS在該URL上,我的測試將成功,如果沒有,它將失敗。 這意味着如果我在實際服務中更改了端點,則測試將失敗:此測試可防止出現副作用 。
其他測試也是如此,所以我猜我不需要解釋它們。
如果你想知道,我沒有單獨做,就像你請求幫助並遵循教程一樣。 但是一旦你習慣它,它就會變得非常快速和容易地測試你的功能。
我希望這會有所幫助,隨時可以問你想要我解釋的任何事情!
模擬服務的想法是你不需要使用實際的功能 (真正的http調用),但你需要服務方法來運行你的代碼,沒有任何例外。
例如:您有一個組件,在某些時候通過Http從某些API收集數據。 其中一個單元測試應該測試你的組件是否進行了這個調用,但如果那里有一個真正的調用你就不會給出該死的。 單元測試的重點是測試呼叫是否已經發生。
編輯:如果某些內部邏輯進行調用以收集數據以顯示某些內容,則會發生同樣的情況。 你應該模擬http調用並返回你自己的數據。 你的單元測試不應該與外界有關。 想象一下,您的測試將在沒有互聯網的環境中運行。 測試應該隨時通過。
無論您測試的是哪種服務,此方案都適用。 單元測試應該具有單一的責任感。 他們不應該依賴於與他們的主要目的不同的東西。
我實際上剛剛在過去的一周遇到過這個問題,所以這在我的腦海中非常新鮮。 Jasmine對我有點困惑,所以我可以分享我為解決問題所做的工作。
首先,Angular教程會誤導新測試人員。 它聲稱我們應該使用Jasmine,但后來開始使用TestBed,這有點誤導。 我最終選擇了TestBed,我可以告訴你我用過的東西。
所以你有你的描述:
descripe('randomService', () -> {
}
你需要初始化你的`randomService':
descripe('randomService', () -> {
let randomService: RandomService;
}
使用beforeEach(),你可以在每個前重新初始化,賦值等, it
在你的描述語句。
descripe('randomService', () -> {
let randomService: RandomService;
beforeEach(() => {
imports: [
HttpClientTestingModule
]
});
}
所以我告訴角度來重新導入HttpClientTestingModule
各之前it
塊。 我的randomService
需要HttpClient
所以我需要創建一個Jasmine Spy對象,它返回我告訴它的內容,而不是讓我的randomService
命中實際的后端並改變后端的實際數據。
descripe('randomService', () -> {
let randomService: RandomService;
httpClientSpy;
beforeEach(() => {
imports: [
HttpClientTestingModule
]
});
httpClientSpy = jasmine.CreateSpyObj('Http', ['get']);
randomService = new RandomService(<any> httpclientSpy);
}
所以現在每當我在randomService中使用'get'方法時,它真的會使用httpClientSpy,並且它編譯因為我告訴randomService我的參數類型為'any'並且它的'最佳知識,實際上是真正的HttpClient即使它不是。 要正確使用此功能,您必須為假冒產品設置假回報:
descripe('randomService', () -> {
let randomService: RandomService;
httpClientSpy;
mockResponse = { 1: ['first', 'second', 'third'] };
beforeEach(() => {
imports: [
HttpClientTestingModule
]
});
httpClientSpy = jasmine.CreateSpyObj('Http', ['get']);
randomService = new RandomService(<any> httpclientSpy);
});
it('should return first, second, third', () => {
spyOn(httpClientSpy, 'get').and.returnValue(Observable.of(mockResponse));
// randomService. <your get method here...>
randomService.getValue().subscribe((response) =>
expect(resposne[0].length).toEqual(3);
};
});
那個響應應該是在我們的beforeEach()
創建的beforeEach()
它不必在beforeEach()中,但是在這個例子中我把它放在那里。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.