ngx-monaco-editor + Karma test runner - как загрузить экземпляр monaco в набор тестов?

Я использую @ materia-ui / ngx-monaco-editor в своем приложении, и мне не удается распознать monaco глобально установленную библиотеку во время выполнения модульных тестов с Karma + Jasmine.

Составная часть

import {
    Component,
    OnInit } from '@angular/core';
import { MonacoEditorLoaderService } from '@materia-ui/ngx-monaco-editor';
import { filter, take } from 'rxjs/operators';

@Component({
    selector: 'my-editor',
    templateUrl: './my-editor.component.html',
    styleUrls: ['./my-editor.component.scss']
})

export class MyEditorComponent implements OnInit {

    public modelUri: monaco.Uri;

    constructor(private monacoLoaderService: MonacoEditorLoaderService) {
        this.monacoLoaderService.isMonacoLoaded$.pipe(
            filter(isLoaded => isLoaded === true),
            take(1),
        ).subscribe(() => {
            this.monacoLoaderService.isMonacoLoaded$
                .pipe(
                    filter(isLoaded => isLoaded),
                    take(1)
                )
                .subscribe(() => {
                    // This seems to be the issue during test runs - monaco is not defined
                    monaco.languages.json.jsonDefaults.setDiagnosticsOptions({});
                })
            })
    }
}

В моем файле компонента monaco разрешается из интерфейсов, представленных в @materia-ui/ngx-monaco-editor:

введите описание изображения здесь

Спецификация испытаний

describe('MyEditorComponent Test Suite:', () => {
    let component: MyEditorComponent;
    let fixture: ComponentFixture<MyEditorComponent>;
    let tagsService: TagsService;
    beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [MyEditorComponent],
            providers: [ MonacoEditorLoaderService ],
            schemas: [CUSTOM_ELEMENTS_SCHEMA]

        }).compileComponents();
    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(MyEditorComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
    });

    it('Should create component', () => {
        expect(component).toBeTruthy();
    });
});

Когда дело доходит до модульного тестирования моего компонента, я получаю сообщение об ошибке от Karma, сообщающее мне, что monaco не определено: введите описание изображения здесь

Я изо всех сил пытаюсь заставить Карма правильно подобрать Монако, по крайней мере, я считаю, что это моя проблема.

При установке @materia-ui/ngx-monaco-editor также устанавливается monaco-editor пакет, поэтому я также попытался добавить скрипт monaco-editor в свойство scripts раздела конфигурации моего тестового проекта в моем файле angular.json:

"test": {
    "builder": "@angular-devkit/build-angular:karma",
    "options": {
      "main": "src/test.ts",
      "karmaConfig": "./karma.conf.js",
      "polyfills": "src/polyfills.ts",
      "tsConfig": "src/tsconfig.spec.json",
      "stylePreprocessorOptions": {
        "includePaths": [
          "src/styles",
          "node_modules"
        ]
      },
      "scripts": [
        "node_modules/monaco-editor/esm/vs/editor/editor.main.js"
      ],
      ...
    }
}

Это не имеет значения, так каков же здесь правильный подход, чтобы правильно зарегистрировать monaco и включить его в мой набор тестов?

ОБНОВЛЕНИЕ

Основываясь на предложении @ Lucho, я воспроизвел свою проблему в следующем Stackblitz - https://stackblitz.com/edit/materia-ngx-monaco-editor-ng9-zdpc2h?file=src/app/app..component.ts

Обратите внимание, что в отличие от подхода Lucho, я не предоставляю MONACO_PATH для пути к CDN, а вместо этого добавляю запись в свойство assets моего приложения и раздел конфигурации тестового проекта файла angular.json, чтобы гарантировать наличие библиотеки monaco-editor. доступен

{
    "glob": "**/*",
    "input": "node_modules/monaco-editor",
    "output": "assets/monaco-editor/"
}

Итак, хотя я пытаюсь предоставить это в тестовом разделе файла angular.json, кажется, что он каким-то образом не используется в реальном тестовом прогоне?


person mindparse    schedule 16.12.2020    source источник


Ответы (1)


Мне удалось заставить один пример работать для вас, но это уродливо IMO, но он выполняет свою работу.

Уродливая часть заключается в том, что я не мог найти способ импортировать монако по всему миру в stackblitz, однако у меня он работал через CDN:

providers: [
    {
      provide: MONACO_PATH,
      useValue: "https://unpkg.com/[email protected]/min/vs"
    }
  ] 

Примечание. Если вы используете Angular 8 ниже, вы должны принять во внимание, что я нашел это тикет, который принудительно устанавливает версию ниже 0.18.1.

Наконец, фактические тесты с тех пор, как я заставил его работать через CDN, к сожалению, вы должны учитывать время получения ресурсов, поэтому вам нужно ввести несколько тайм-аутов и сообщить жасмину, когда все закончится:

beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [AppModule],
      providers: [],
      declarations: []
    }).compileComponents();

    setTimeout(() => {
      fixture = TestBed.createComponent(AppComponent);
      component = fixture.componentInstance;
      fixture.detectChanges();
    }, 1000);
    jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
  }));

  it("Should create component", async(done: DoneFn) => {
    setTimeout(() => {
      expect(component).toBeTruthy();
      done();
    }, 2000);
  });

  it("Check if code in editor is populated", async(done: DoneFn) => {
    setTimeout(() => {
      let code = component.monacoComponent.editor.getValue();
      expect(code).toEqual(expectedCode);
      done();
    }, 2000);
  });

Вот рабочий stackblitz с тестами, НАСЛАЖДАЙТЕСЬ!

person Lucho    schedule 16.12.2020
comment
Спасибо @Lucho, я бы предпочел не добавлять явные таймауты к тестам, поскольку это в конечном итоге приводит к нестабильности теста. Я собираюсь обновить свой вопрос дополнительным stackblitz, который лучше продемонстрирует мою настройку и, надеюсь, поможет в диагностике проблемы. - person mindparse; 17.12.2020
comment
Я предполагаю, что вы пробовали использовать import * as monaco from 'monaco-editor'; в своем компоненте, что означает, что вам нужно использовать неглобальный подход? - person Lucho; 18.12.2020
comment
Привет, хорошие идеи! Я просто попробовал, но stackblitz жалуется, что не может найти пакет monaco-editor, хотя я вижу, что он установлен как зависимость. Я попытался удалить и переустановить, но это не имело никакого значения - разочарование! - person mindparse; 18.12.2020
comment
Не делайте этого в stackblitz, делайте это локально, где вы запускаете свои тесты. - person Lucho; 18.12.2020
comment
Хм, когда я пытаюсь, я получаю ошибки от компилятора из-за повторяющихся определений, найденных между node_modules/@materia-ui/ngx-monaco-editor/lib/interfaces/monaco.d.ts и node_modules/monaco-editor/esm/vs/editor/editor.api.d.ts. Типизация, поступающая из @materia-ui, уже включает экспорт пространства имен monaco. - person mindparse; 18.12.2020
comment
В вашем файле tsconfig.json добавьте "exclude": [ "node_modules/monaco-editor/esm/vs/editor/editor.api.d.ts" ] с предположением, что editor.api.d.ts расширен в monaco.d.ts - person Lucho; 18.12.2020
comment
или даже лучше в свойстве asset, где вы обновили свой пост, добавьте "ignore": [ "node_modules/monaco-editor/esm/vs/editor/editor.api.d.ts" ] - person Lucho; 18.12.2020
comment
Все еще не работаю, я сдался и теперь заглушил объект monaco и необходимые реквизиты, к которым мой компонент должен получить доступ, на global, который представлен в наборе тестов. У меня это работает достаточно хорошо, а значит, я могу легко настроить шпионов, если они мне понадобятся. - person mindparse; 18.12.2020
comment
@mindparse Не могли бы вы объяснить, как вы исправили ошибку? Я также застрял с той же проблемой в данный момент, и мне не удалось найти какое-либо исправление. - person Rakesh Pethani; 07.06.2021