Angular+Jest测试Rete.js组件遇导入路径错误求助
Angular + Rete.js 组件测试导入路径错误问题
我正在为一个基于Rete.js的Angular组件编写简单测试,但测试一直失败,原因是无法解析某条导入路径。哪怕在测试里Mock了EditorCreatorService而不是直接注入,这个导入错误还是存在。以下是相关代码和错误截图:
组件代码
import { Component, ElementRef, Injector, ViewChild } from '@angular/core'; import { EditorCreatorService } from './edtitor-creator'; @Component({ selector: 'exb-visual-workflow-editor', templateUrl: 'visual-workflow-editor.component.html', styleUrls: ['visual-workflow-editor.component.scss'], }) export class VisualWorkflowEditorComponent { @ViewChild('rete') container!: ElementRef; constructor(private injector: Injector, private readonly editorCreatorService: EditorCreatorService) {} ngAfterViewInit(): void { const el = this.container.nativeElement; if (el) { this.editorCreatorService.createEditor(el, this.injector); } } }
服务代码
import { NodeEditor, GetSchemes, ClassicPreset } from 'rete'; import { Injector, Injectable } from '@angular/core'; import { AreaPlugin } from 'rete-area-plugin'; import { ConnectionPlugin, Presets as ConnectionPresets } from 'rete-connection-plugin'; import { AngularPlugin, AngularArea2D, Presets as AngularPresets } from 'rete-angular-plugin/16'; // --> 导入错误 import { CustomSocketComponent } from './customization/custom-socket/custom-socket.component'; import { CustomNodeComponent } from './customization/custom-node/custom-node.component'; import { CustomConnectionComponent } from './customization/custom-connection/custom-connection.component'; import { addCustomBackground } from './customization/custom-background'; type Schemes = GetSchemes<ClassicPreset.Node, ClassicPreset.Connection<ClassicPreset.Node, ClassicPreset.Node>>; type AreaExtra = AngularArea2D<Schemes>; const socket = new ClassicPreset.Socket('socket'); @Injectable() export class EditorCreatorService { async createEditor(container: HTMLElement, injector: Injector) { const editor = new NodeEditor<Schemes>(); const area = new AreaPlugin<Schemes, AreaExtra>(container); const connection = new ConnectionPlugin<Schemes, AreaExtra>(); const angularRender = new AngularPlugin<Schemes, AreaExtra>({ injector }); angularRender.addPreset( AngularPresets.classic.setup({ customize: { node() { return CustomNodeComponent; }, connection() { return CustomConnectionComponent; }, socket() { return CustomSocketComponent; }, }, }), ); connection.addPreset(ConnectionPresets.classic.setup()); addCustomBackground(area); editor.use(area); area.use(connection); area.use(angularRender); const aLabel = 'Custom'; const bLabel = 'Custom'; const a = new ClassicPreset.Node(aLabel); a.addOutput('a', new ClassicPreset.Output(socket)); a.addInput('a', new ClassicPreset.Input(socket)); await editor.addNode(a); const b = new ClassicPreset.Node(bLabel); b.addOutput('a', new ClassicPreset.Output(socket)); b.addInput('a', new ClassicPreset.Input(socket)); await editor.addNode(b); await area.translate(a.id, { x: 0, y: 0 }); await area.translate(b.id, { x: 300, y: 0 }); await editor.addConnection(new ClassicPreset.Connection(a, 'a', b, 'a')); return { destroy: () => area.destroy(), }; } }
测试代码
import { EditorCreatorService } from './edtitor-creator'; import { VisualWorkflowEditorComponent } from './visual-workflow-editor.component'; import { render, RenderResult } from '@testing-library/angular'; describe('WorkflowEditorComponent', () => { let component: RenderResult<VisualWorkflowEditorComponent>; let createEditorSpy: jest.SpyInstance; let editorCreatorServiceMock: Partial<EditorCreatorService>; beforeEach(async () => { editorCreatorServiceMock = { createEditor: jest.fn().mockReturnValue({}), }; component = await render(VisualWorkflowEditorComponent, { providers: [ { provide: editorCreatorServiceMock, }, ], }); createEditorSpy = jest.spyOn(editorCreatorServiceMock, 'createEditor'); }); it('should create', () => { expect(createEditorSpy).toHaveBeenCalledTimes(1); }); });
错误截图

解决方法
1. 先修复测试里的Provider配置错误
你测试代码里的Provider写反了,provide字段要填服务的类EditorCreatorService,useValue才是你的mock对象,正确写法:
providers: [ { provide: EditorCreatorService, useValue: editorCreatorServiceMock, }, ]
原代码直接把mock对象传给provide,Angular压根不知道要替换哪个服务,导致测试时还是会加载真实的EditorCreatorService类,自然触发导入错误。
2. 处理Rete插件的导入路径问题
如果修复Provider后还是报错,说明测试环境认不出rete-angular-plugin/16这个路径,试试下面的方案:
- 核对依赖版本:路径里的
16对应Angular 16,确认你安装的rete-angular-plugin版本和Angular版本匹配,不匹配的话要么换插件版本,要么调整Angular版本。 - 添加路径映射:在
tsconfig.spec.json里加路径映射,告诉测试环境怎么找这个模块:{ "compilerOptions": { "paths": { "rete-angular-plugin/16": ["node_modules/rete-angular-plugin/dist/16"] } } } - Mock整个Rete模块:如果测试只需要验证组件调用了
createEditor,不需要真的初始化Rete编辑器,可以在测试文件顶部Mock所有Rete相关依赖:
这样测试时就不会加载真实的Rete模块,也就不会触发导入错误了。// 先Mock rete-angular-plugin jest.mock('rete-angular-plugin/16', () => ({ AngularPlugin: jest.fn(), AngularArea2D: jest.fn(), Presets: { classic: { setup: jest.fn().mockReturnValue({}) } } })); // 再Mock其他Rete相关依赖 jest.mock('rete', () => ({ NodeEditor: jest.fn(), GetSchemes: jest.fn(), ClassicPreset: { Socket: jest.fn(), Node: jest.fn(), Output: jest.fn(), Input: jest.fn(), Connection: jest.fn() } })); jest.mock('rete-area-plugin', () => ({ AreaPlugin: jest.fn() })); jest.mock('rete-connection-plugin', () => ({ ConnectionPlugin: jest.fn(), Presets: { classic: { setup: jest.fn() } } }));
3. 检查测试环境的构建配置
如果用Angular CLI的测试环境,看看angular.json里的test配置,确保包含了rete-angular-plugin的文件,或者在tsconfig.spec.json的include字段里加上必要的路径。
内容的提问来源于stack exchange,提问作者Miguel Frias
相关产品推荐
相关产品推荐

