Angular 2+ 服务测试。服务导入在 ng 测试运行时未定义

Angular 2+ Service Testing. Service imports are undefined at ng test runtime

我是 Angular 的新手,正在尝试测试 Angular 6 服务,该服务利用 handlebars.js 构建客户端 html 模板,基于输入 JSON/数据.

该服务在开发过程中产生了预期的结果,但我无法构建测试来确认该服务编译 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);
    }
  ));
});

我已经尝试改变服务和多种不同的方法来通过测试传递变量,但它们始终未定义。任何帮助将不胜感激!

单元测试中使用的典型方法只是为了确保您的代码正在做它应该做的事情,而不是测试从第三方库返回的数据。因此,我建议监视 Handlebars 的方法,以便在测试期间不会实际调用它们,但您可以测试您的服务如何尝试调用它们。

根据您上面写的内容,我搭建了一个stackblitz测试环境来尝试一些想法。它在这里:https://stackblitz.com/edit/Whosebug-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);
  }));
});

希望对您有所帮助。