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

标签 angular angular2-services angular2-testing angular-test

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

该服务在开发过程中产生了预期的结果,但我无法构建一个测试来确认该服务正确编译了 html。我将基本模板(作为 JavaScript 字符串)直接导入到服务中,但是当我尝试在 .spec 文件中运行编译方法时,我收到 错误:您必须将字符串或 Handlebars AST 传递给 Handlebars.compile。您传递了未定义的,这意味着基本模板字符串变量未在 .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/stackoverflow-q-53075746?file=app%2Fpdf-reports.service.spec.ts .随意将其 fork 到您自己的 stackblitz 帐户中并使用它 - 我没有任何数据可以放入各种测试文件中,并且对 Handlebars 的了解不足以正确导入它。尽管如此,我还是能够对您的服务进行工作测试。

基本上我在那里所做的是在 spec 文件中导入 Handlebars 这样我就可以窥探它的方法,然后将 spec 更改为以下内容:

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);
  }));
});

希望对您有所帮助。

关于Angular 2+ 服务测试。服务导入在 ng 测试运行时未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53075746/

相关文章:

angular - 如果 '<x>' 是一个 Angular 组件,那么验证它是这个模块的一部分

css - 选中按钮后如何在按钮下放置一行?

angular - 如何在 Angular 2 final 中扩展 Angular 2 http 类

angular - angular2 中的多供应商是什么

angular - 在服务中使用 observables 测试错误案例

Angular Material DatePicker : Date becomes one day before selected date

angular - 带有后端分页的 ng2-smart-table (Spring)

Angular 2 测试 - 异步函数调用 - 何时使用

unit-testing - 如何对依赖于 ActivatedRoute 参数的组件进行单元测试?

java - 将 jsp 页面移至 Angular 7