ReferenceError: customElements is not defined



我正在使用@angular@9.0.7@ngneat/spectator@5.3.1(带有Jest(、Inputmask@5.0.3在项目中,当我运行ng serve甚至ng build时,应用程序上的一切都可以工作,但当我尝试为使用Inputmask:的@Pipe运行测试套件时,它失败了

@Pipe

import { Pipe, PipeTransform } from '@angular/core';
import Inputmask from 'inputmask';
@Pipe({
name: 'appSomePipe',
})
export class SomePipe implements PipeTransform {
transform(value: string): string {
return Inputmask.format(value, {
jitMasking: true,
mask: '1111-1',
});
}
}

@Spec

import { createPipeFactory, SpectatorPipe } from '@ngneat/spectator/jest';
import { SomePipe } from './some.pipe';
describe('SomePipe', () => {
let spectator: SpectatorPipe<SomePipe>;
const createPipe = createPipeFactory(SomePipe);
it('test', () => {
spectator = createPipe(`{{ '11111' | appSome }}`);
expect(spectator.element).toHaveText('1111-1');
});
});

当我运行ng test时,它显示:

ReferenceError:customElements未定义

2 | 
> 3 | import Inputmask from 'inputmask';

PS:此错误仅出现在Angular 9中,在Angular 8中,所有测试都成功通过。

快速搜索inputmask存储库显示,它使用customElements,这是现代浏览器实现的一项功能,用于创建本地web组件(无框架(。

在查看Jest文档时,我们可以看到默认的testEnvironment是jsdom,它是在没有浏览器的情况下运行的DOM的实现。这个库从16.2.0版本开始实现自定义元素,这个版本是最近的版本,jest还没有使用它(jest的上一个版本使用jsdom v15.1.1(。

因此,您只需要等待jest更新jsdom依赖项,然后更新您的项目以使用最新版本的jest。

另一种选择:你可以使用jest浏览器,它在基于puppeteer的无头浏览器中运行jest。

更新05-2020:

升级至(至少(使用jsdom 16.2.0(Source(的Jest 26.0.0

正如Guerric p所写,jsdom在v16.2.0之前不支持customElements。

要使用jsdomv16运行jest,您需要执行以下

yarn add jest-environment-jsdom-sixteen

然后在你的jest.config.js中添加这个

module.exports = {
testEnvironment: 'jest-environment-jsdom-sixteen',
...
}

这将迫使jest使用更新的实现。这应该能解决你的问题。

我记得我偶然发现了你的问题,还偶然发现了与ngx-bootstrap有关的其他事情,即import不在Angular 9中工作。

https://valor-software.com/ngx-bootstrap/#/datepicker

查看有关Angular 9的用法部分及其警告。

尝试从"inputmask"执行import InputMask from 'inputmask/somethingMoreSpecificHere';或"import{somethingSpecificHere}";

问题是您没有将Inputmask依赖项注入到测试中。

这是因为您使用的是javascript导入。有Angular库可以做到这一点(ngx掩码(。

在Angular中,我们将依赖项注入与IOC一起使用,因此在本例中,我将使用InputMaskService来创建角度依赖项。

管道

import { Pipe, PipeTransform } from '@angular/core';
import { InputMaskService } from './inputmask.service';
@Pipe({
name: 'appSomePipe',
})
export class SomePipe implements PipeTransform {
constructor(private inputMaskService: InputMaskService){}
transform(value: string): string {
return this.inputMaskService.format(value, {
jitMasking: true,
mask: '1111-1',
});
}
}

请注意,我正在构造函数中注入服务,并在transform方法中使用该实例。

测试

您可以创建一个通过服务引用的管道实例

beforeEach(() => {
const inputMaskService = new InputMaskService();
const pipe = new SomePipe(inputMaskService);
});

最新更新