Как смоделировать Angular внешний Javascript объект - PullRequest
0 голосов
/ 24 марта 2020

У меня есть приложение angular, единственной целью которого является сборка @ angular / elements (без индекса. html, без app.component и т. Д. c.).

Эти элементы используются в приложении. NET Mvc, которое предоставляет два вида вещей, которые я пытаюсь смоделировать в своих модульных тестах:

1 - внешние библиотеки

Например, JQuery, loda sh et c.

2 - Клиентская структура "foo"

Внутри. NET MVC представления, включающего мои веб-элементы, MVC Приложение создает объект с именем foo. Этот объект не является модулем ES6. Он создается вручную с красивым foo = new Foo ({someOptionsGeneratedFromServerSide});

Оба случая используются внутри моих веб-элементов. Например, компонент будет использовать функцию foo.displayAlert («С сообщением»). Единственное решение, которое я нашел, чтобы заставить мое angular приложение выполнить это, - добавить следующее:

// tslint:disable-next-line: max-line-length no-reference
/// <reference path='path/to/the/definition.d.ts' />

Я знаю, что это совершенно не ортодоксально.

Angular Приложение работает нормально, пока я не попытаюсь провести какое-то модульное тестирование. Примечание: он не может работать в одиночку (ng serve бесполезен, как и ожидалось).

Пример

it('should render title', () => {
  const fixture = TestBed.createComponent(AppComponent);
  fixture.detectChanges();
  const compiled = fixture.nativeElement;
  expect(compiled.querySelector('.content span').textContent).toContain('ng-jest app is running!');
});

Для этого компонента / ловушки:

ngOnInit() {
  foo.displayAlert('With a message');
}

Будет cra sh со следующим (вполне ожидаемым) сообщением:

AppComponent › should render title
ReferenceError: foo is not defined

Я пытался явно высмеивать объект перед тестом:

  let foo: any;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule
      ],
      declarations: [
        AppComponent
      ],
    }).compileComponents();
    foo = {
      displayAlert: Function
    };
  }));

Пока не повезло. Я сделал много попыток насмешки внутри x.spect.ts по поводу этого объекта безрезультатно.

Я пытался создать другое приложение Angular с индексом. html, которое включает все ресурсы, такие как MVC просмотр, но не удалось.

Заключительные примечания

Для сторонних организаций, таких как JQuery / loda sh, я не буду sh добавлять их в мой Angular проект например: npm i -D lodash, поскольку я не хочу, чтобы они были включены в мой файл поставщика. js. Эти библиотеки предоставляются приложением. Net Mvc, и это нормально. Это относится и к объекту foo. Наконец, я попробовал с (Jest) и без (Karma) безголовый браузер для тестов.

Любая помощь будет очень признательна!

Редактировать 27/03/2020

Пожалуйста, спасите меня!

Редактировать 28/03/2020

Пробовал jasmine.createSpyObject & spyOn, тоже не повезло: (

1 Ответ

1 голос
/ 29 марта 2020

Сложная настройка, вы сами себе это не облегчаете.

Однако, похоже, вам просто нужно подделать foo как глобальную переменную, поскольку глобальная область действия - это то, где ваш компонент ожидает, что переменная будет , Когда вы объявляете let foo внутри модуля ECMAScript, вы создаете переменную в этом файле, к которой ваш компонент не может получить доступ.

beforeEach(() => {
  window.foo = {
    displayAlert: () => {},
  };
});

Это, вероятно, заставит вас бороться с TypeScript. Это исправление

beforeEach(() => {
  (window as any).foo = {
    displayAlert: () => {},
  };
});
...