![](/img/trans.png)
[英]Implement unit testing with jasmine/karma by mocking Http Post - Angular 5
[英]Angular 4 unit testing with jasmine /karma with http post mocking - how to fix
我有一個服務,我想在角度4打字稿茉莉中進行單元測試。
現在, http
正在post
,它返回一個標識,但是..它沒有發送任何內容。
我只想擁有良好的代碼覆蓋率,但我不明白如何完全完成此模擬語句。
這是我的服務文件中http發布的方法
addSession() {
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });
return this.http.post(this.url, JSON.stringify({}), options)
.map((response: Response) => response.json());
}
然后是SPEC FILE ,我沒有真正測試的東西,我想是冒充我從服務http帖子收到了一個數字,響應應該是000000014
規格
import { TrackerFormService } from './tracker-form.service'
import { Observable } from 'rxjs/Observable'
describe('TrackerFormService', () => {
let trackerFormService: TrackerFormService,
mockHttp;
beforeEach(() => {
mockHttp = jasmine.createSpyObj('mockHttp', ['get', 'post', 'put']
)
trackerFormService = new TrackerFormService(mockHttp);
});
describe('addSession', () => {
it('add session ', () => {
// how to test, what to test?
// response , is a number? how to mock/fake this?
})
})
})
為了實現所需的功能,所需的模擬程序是一個簡單的函數,該函數返回的結果與POST正常執行的結果相同; 另一件事是您的測試不應真正在服務器上運行,因此您將需要以下內容(您可能需要添加其他依賴項):
import { HttpModule } from '@angular/http';
import { TrackerFormService } from './tracker-form.service'
import { Observable } from 'rxjs/Observable'
describe('TrackerFormService', () => {
// Mock the service like this and add all the functions you have in this fashion
let trackerFormService: TrackerFormService,
mockService = {
addSession: jasmine.createSpy('addSession').and.returnValue(Observable.of('your session object mock goes here'))
};
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpModule],
providers: [{
provide: TrackerFormService,
useValue: mockService
}]
});
});
// Do this trick to inject the service every time, and just use `service` in your tests
beforeEach(inject([TrackerFormService], (trackerFormService) => {
service = trackerFormService;
}));
describe('addSession', () => {
it('add session ', () => {
let fakeResponse = null;
// Call the service function and subscribe to it to catch the fake response coming from the mock.
service.addSession().subscribe((value) => {
// in here value will be whatever you put as returnValue (remember to keep the observable.of())
fakeResponse = value;
});
// expects as in any test.
expect(fakeResponse).toBeDefined();
expect(fakeResponse).toBe('your session object mock goes here');
});
});
});
Angular 4.3附帶了HttpClient服務,該服務取代了Http,並提供了一種簡單的模擬HTTP請求的方法。 在官方頁面上有很好的記錄: https : //angular.io/guide/http
很好,您可以通過設置測試/模擬的方式來偽造郵寄回郵,並檢查是否獲得了預期的結果。 通過這樣做,您將測試map語句將正確轉換模擬的響應。 通過您的間諜,您還可以檢查post方法的調用方式。 這將檢查選項是否符合您的期望。
但是我認為這是一個相當復雜的解決方案。 我寧願通過拆分方法來避免模擬和間諜,因此每種方法都只是做一件事。 因為您的addSession方法當前正在執行三種不同的操作(但在邏輯上是依賴的):
如果將方法分成三部分,則可以在單獨的測試中輕松測試方法1和方法3,方法2僅包含對http庫的調用。 這樣,您無需調用http庫即可獲得與上述相同的測試值。
現在關於方法2呢...它仍然未經測試,我認為根本沒有理由對其進行測試。 因為您沒有編寫該代碼。 另外,如果您使用的是angulars http模塊,那么我可以確定它們本身具有可靠的單元測試。
您的服務的響應應該已經包含在附加的集成測試中,以較少的頻率運行,檢查服務api仍會返回您期望的結果。
如果您確實希望代碼覆蓋范圍內的一行為綠色,則可以選擇使用一個名為nock的庫。 Nock會攔截您的應用程序引起的所有xhr流量。 在您的測試文件中,您可以將xhr請求映射到帶有nock對象的模擬響應。
var scope = nock('http://myapp.iriscouch.com') .post('/users', { username: 'pgte', email: 'pedro.teixeira@gmail.com' }) .reply(201, { ok: true, id: '123ABC', rev: '946B7D1C' });
復制自: https : //www.npmjs.com/package/nock
有關一般測試以及要測試多少的參考和其他信息,我建議觀看Justin Searls的“預算現實”
HTTP服務請求的示例測試用例
describe('Forgot Password Controller', function () { var $controller, $httpBackend, $q, $rootScope, $state, controller, scope, accountProvider; beforeEach(module('app')); beforeEach(inject(function (_$injector_, _$controller_, _$rootScope_) { $controller = _$controller_; $rootScope = _$rootScope_; $httpBackend = _$injector_.get('$httpBackend'); $state = _$injector_.get('$state'); $q = _$injector_.get('$q'); accountProvider = _$injector_.get('accountProvider'); scope = _$rootScope_.$new(); controller = $controller(app.controllers.forgotPassword, { $state: $state, accountProvider: accountProvider }); })); afterEach(function () { $httpBackend.verifyNoOutstandingRequest(); $httpBackend.verifyNoOutstandingExpectation(); }); describe('forgot password submission', function () { it('Can submit a forgot password request successfully', function () { $httpBackend.expectPOST("URL DOMAIN" + '/events/requestPasswordReset').respond(200); spyOn($state, 'go'); controller.form = { emailAddress: 'aks@gmail.com' }; controller.submit(); expect(controller.submitting).toBe(true); $httpBackend.flush(); expect(controller.submitting).toBe(false); expect($state.go).toHaveBeenCalledWith('login', { successMessage: 'An email sent to ' + controller.form.emailAddress + ' contains instructions for resetting your password.' }); }); it('Can handle when a user is not found when submitting a forgot password request', function () { $httpBackend.expectPOST(app.env.EDGE_SERVICE_PATH + '/events/requestPasswordReset').respond(404); spyOn($state, 'go'); controller.form = { emailAddress: 'aks@gmail.com' }; controller.submit(); expect(controller.submitting).toBe(true); $httpBackend.flush(); // We intentionally want to make it appear to the user that the password reset email was sent even when a user // does not exist, to help hide info about which users exist in the system expect(controller.submitting).toBe(false); expect($state.go).toHaveBeenCalledWith('login', { successMessage: 'An email sent to ' + controller.form.emailAddress + ' contains instructions for resetting your password.' }); }); it('Can handle unexpected errors from submitting a forgot password request', function () { $httpBackend.expectPOST("URL DOMAIN" + '/events/requestPasswordReset').respond(500); controller.submit(); $httpBackend.flush(); expect(controller.errors.unexpectedError).toBe(true); }); it('Can handle 422 validation errors from submitting a forgot password request', function () { var responseData = { fieldErrors: { username: [{code: 'error'}, {code: 'required', message: 'This is required.'}] } }; $httpBackend.expectPOST("URL DOMAIN" + '/events/requestPasswordReset').respond(422, responseData); controller.submit(); $httpBackend.flush(); expect(controller.errors.validationErrors).toBe(true); expect(controller.errors.fieldErrors).toEqual(responseData.fieldErrors); }); it('Can handle 503 service unavailable from submitting a forgot password request', function () { $httpBackend.expectPOST("URL DOMAIN" + '/events/requestPasswordReset').respond(503); controller.submit(); $httpBackend.flush(); expect(controller.errors.serviceUnavailable).toBe(true); }); }); });
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.