引用错误:customElements未定义。

11
我正在使用@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 is not defined

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

注意:这个错误只在Angular 9中出现,在Angular 8中所有的测试都已经成功通过。

4个回答

11
在存储库中进行快速搜索,可以看到它使用了customElements,这是现代浏览器实现的一项功能,用于创建本机Web组件(无需框架)。
查看Jest文档时,我们可以看到默认的testEnvironmentjsdom,它是一个在没有浏览器的情况下运行的DOM实现。该库自16.2.0版本开始实现了自定义元素,这个版本很新,jest尚未使用(jest的最后一个版本使用jsdom v15.1.1)。
因此,您只需要等待jest更新jsdom依赖项,然后更新项目以使用最新版本的jest。
另一个选择:您可以使用jest-browser,它基于puppeteer在无头浏览器中运行Jest。

更新 05-2020:

升级至(至少)Jest 26.0.0,它使用jsdom 16.2.0(来源


谢谢。正如我所说,问题是在包更新(Angular [8x -> 9x],Spectator [4x -> 5x],Jest [15x -> 16x]等)后开始出现的,由于某种原因,我认为问题出在新版本的Angular或Spectator上,完全忘记了Jest。无论如何,将Jest版本降级到15x后,一切都恢复正常了。我希望他们能尽快在16x中修复它。 - dev_054
很高兴能帮到你! - Guerric P
啊,我差点忘了……在修复 Jest 的问题之后,我不得不将导入从 import Inputmask from 'inputmask'; 更改为 import { format } from 'inputmask'; 才能使其在 Angular 9 上正常工作。 - dev_054

4

据Guerric P所述,jsdom直到v16.2.0才支持customElements。

要让jest在jsdom v16上运行,您需要执行以下操作:

yarn add jest-environment-jsdom-sixteen

然后在你的 jest.config.js 中添加以下内容。
module.exports = {
  testEnvironment: 'jest-environment-jsdom-sixteen',
  ...
}

这将强制Jest使用更新的实现方式。这应该解决你的问题。

0

我记得偶然看到了你的问题,然后又发现了与ngx-bootstrap相关的另一件事,涉及到在Angular 9import无法正常工作的问题。

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

请查看使用部分及其有关Angular 9的警告。
尝试执行import InputMask from 'inputmask/somethingMoreSpecificHere';或`import { somethingSpecificHere } from 'inputmask';


谢谢你的回答,但不幸的是它还是不能工作。我试过 import { format } from 'inputmask',但仍然显示相同的错误 :/。 import InputMask from 'inputmask/somethingXXX' 是不可行的。 - dev_054

-2
问题在于您没有将Inputmask依赖项注入到测试中。
这是因为您正在使用JavaScript导入。有Angular库可以解决这个问题( ngx-mask)。
在Angular中,我们使用具有IOC的依赖注入,因此对于这个示例,我将使用InputMaskService来创建Angular依赖项。
管道
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);
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接