Angular 2+ Сервисное тестирование. Импорт службы не определен во время выполнения теста ng
Я новичок в Angular и пытаюсь протестировать сервис Angular 6, который использует handlebars.js для создания клиентских html-шаблонов на основе входных данных JSON / data.
Служба дает желаемый результат в процессе разработки, но я не могу создать тест, подтверждающий, что служба правильно компилирует HTML. У меня есть базовые шаблоны (как строки JavaScript), импортированные непосредственно в сервис, но когда я пытаюсь запустить метод компиляции в файле.spec, я получаю Error: You must pass a string or Handlebars AST to Handlebars.compile. You passed undefined
Это означает, что строковые переменные базового шаблона не создаются в службе в файле.spec.
PdfReportService.service.ts
файл
import { Injectable } from '@angular/core';
import * as Handlebars from 'handlebars/dist/handlebars.min.js';
// base template
import base_html from './root_template/html';
// form templates
import form_html from './form_template/form.html';
import form_css from './form_template/form.css';
@Injectable({
providedIn: 'root'
})
export class PdfReportService {
...
...
public compileform(json: object, context?: any) {
Handlebars.registerPartial({ hbs_css_template: form_css });
Handlebars.registerPartial({ hbs_form_body: form_html });
return Handlebars.compile(base_html)({ json, context });
}
}
PdfReportService.service.spec.ts
файл
import { TestBed, inject } from '@angular/core/testing';
import { PdfReportService } from './pdf-reports.service';
// import test data
import {
formInputJson,
formInputContext,
formCompiledHTML
} from './pdf-reports.service.spec.data';
fdescribe('PdfReportService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [PdfReportService]
});
});
it('should compile the correct html from form input data', inject(
[PdfReportService],
(service: PdfReportService) => {
const result = service.compileform(formInputJson, formInputContext);
expect(result).toEqual(formCompiledHTML);
}
));
});
Я пытался изменить сервис и несколько различных методов прохождения переменных через тест, но они всегда остаются неопределенными. Любая помощь будет оценена!
1 ответ
Типичная методология, используемая в модульном тестировании, заключается просто в том, чтобы убедиться, что ваш код делает то, что должен, а не тестировать данные, возвращенные из сторонних библиотек. Поэтому я бы посоветовал шпионить за методами Handlebars, чтобы они не вызывались во время тестирования, но вы можете проверить, как ваша служба пытается вызвать их.
Основываясь на том, что вы написали выше, я настроил среду тестирования stackblitz, чтобы опробовать несколько идей. Это здесь: https://stackblitz.com/edit/stackru-q-53075746?file=app%2Fpdf-reports.service.spec.ts. Не стесняйтесь раскошелиться на свою учетную запись stackblitz и поэкспериментировать с ней - у меня не было данных, которые можно было бы поместить в различные тестовые файлы, и я недостаточно хорошо знаю Handlebars, чтобы импортировать их должным образом. Тем не менее, я смог получить рабочий тест вашего сервиса.
По сути, я сделал импорт Handlebars из файла спецификации, чтобы я мог следить за его методами, а затем изменить спецификацию следующим образом:
it('should compile the correct html from form input data', inject(
[PdfReportService],
(service: PdfReportService) => {
const returnFunc = jasmine.createSpy('returnFunc').and.returnValue(formCompiledHTML);
const regPartialSpy = spyOn(Handlebars, 'registerPartial');
const compileSpy = spyOn(Handlebars, 'compile').and.returnValue(returnFunc);
const result = service.compileform(formInputJson, formInputContext);
expect(regPartialSpy).toHaveBeenCalledTimes(2);
expect(compileSpy).toHaveBeenCalledWith({/* base_html */});
expect(returnFunc).toHaveBeenCalledWith({ json: jasmine.any(Function), context: jasmine.any(Function) });
expect(result).toEqual(formCompiledHTML);
}));
});
Я надеюсь, что это полезно.