У меня есть служба Angular v6, которая вызывает основной API .net и получает большой двоичный объект, представляющий собой PDF-файл. Когда он получает ответ OK от API, служба также устанавливает флаг в значение true, который используется компонентом.
Я пытаюсь написать модульный тест Jasmine для этого поведения, и он продолжает сообщать, что флаг ложный (но предлагает мне загрузить поддельный файл). Karma сообщает: Expected undefined to be truthy. При использовании развернутого кода все выглядит правильно, поэтому я считаю, что это ошибка в модульном тесте.
Это мое первое приложение на Angular 6, использующее Typescript, так что это может быть ошибка в чем-то более простом.
Обслуживание:
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { saveAs } from 'file-saver';
import { environment } from '../environments/environment';
import { InputParameters } from './inputParameters';
@Injectable({
providedIn: 'root'
})
export class SettlementService
{
success: boolean;
private apiUrl = environment.apiURL;
constructor(private http: HttpClient) { }
getSettlement(inputParms: InputParameters, captchaResponse: string)
{
//add captcha response header
let headers: HttpHeaders = new HttpHeaders();
headers = headers.append('g-recaptcha-response', captchaResponse);
//submit post request to service layer
return this.http
.post(this.apiUrl, inputParms, { responseType: 'blob', observe: 'response', headers: headers })
.toPromise()
.then(response =>
{
this.success = true;
this.saveToFileSystem(response);
})
.catch((reason: Response) =>
{
this.success = false;
console.info(reason);
//alert("Settlement not found!");
});
}
private saveToFileSystem(response)
{
//get the file name from the content-disposition header
const contentDispositionHeader: string = response.headers.get('Content-Disposition');
const parts: string[] = contentDispositionHeader.split(';');
const fileName = parts[1].split('=')[1];
const blob = new Blob([response.body], { type: 'application/pdf' });
saveAs(blob, fileName);
}
}
Модульный тест сервиса, который я тестирую:
import { TestBed, inject, getTestBed, tick, fakeAsync } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { SettlementService } from './settlement.service';
import { InputParameters } from './inputParameters';
describe('SettlementService', () =>
{
let injector: TestBed;
let service: SettlementService;
let httpMock: HttpTestingController;
beforeEach(() =>
{
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [SettlementService]
});
injector = getTestBed();
service = injector.get(SettlementService);
httpMock = injector.get(HttpTestingController);
});
afterEach(() =>
{
httpMock.verify();
});
it('should download a file and success should be true', (() =>
{
//arrange
//return blob
const file = new Blob(['ATESTFILE'], { type: 'application/pdf' });
//setup input parms
let parms: InputParameters = new InputParameters();
parms.agreementNumber = '001234567898';
parms.bankAccountNumber = '00112233';
var date: Date = new Date();
date.setFullYear(date.getFullYear() - 20);
parms.dateOfBirth = date;
//act
service.getSettlement(parms, '0000000');
//assert
expect(service.success).toBeTruthy();
const req = httpMock
.expectOne('http://localhost:5000/api/settlement');
expect(req.request.headers.has('g-recaptcha-response'));
expect(req.request.method).toEqual('POST');
//act
req.flush(file, {
headers: { 'Content-Disposition': 'attachment; filename = "testfilename.pdf"' },
status: 200,
statusText: 'OK'
});
}));
добавил его в q, но его Expected undefined to be truthy.
Я думаю, вам нужно подождать, пока служба разрешит блокировку .then, прежде чем утверждать, что success является правдой. Поскольку метод возвращает обещание, вы можете просто использовать: await service.getSettlement(parms, '0000000');, но для использования await вам нужно будет добавить async, поэтому описание it станет: it('should download a file and success should be true', async (() =>
Это изменило ошибку на: Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL, а затем Error: Expected no open requests, found 1: POST http://localhost:5000/api/settlement, который, как я предполагаю, взят из блока afterEach.
Вам необходимо подписаться на свой service.getSettlement (...), и в рамках этой подписки вы можете проверить свое ожидание (service.success) .toBeTruthy (). Как упоминалось в cjb100, вы проверяете свойство успеха до того, как будет сделан запрос.





Опубликуйте вывод полученной ошибки. Тест выглядит неплохо.