Выпуск страниц-макетов при тестировании вкладок Ionic v3 с помощью ngMocks и угловой анимации - PullRequest
0 голосов
/ 25 января 2019

У меня есть проект, который использует Angular 4 и Ionic v3 и Jest.Мы создали приложение, которое использует интерфейс Ionic Tab, но у меня возникают проблемы, когда я пытаюсь написать тесты для этого.

Для начала, вот файлы:

tabs.ts

import { Component, ViewChild, ChangeDetectorRef } from '@angular/core';
import { Content } from 'ionic-angular';
import { ShowService } from '../../app/services/show.service';
import { LoggerService } from '../../app/services/logger.service';
import { HighlightsPage } from '../highlights/highlights';
import { ShowsPage } from '../shows/shows';
import { ConnectPage } from '../connect/connect';
import { SettingsPage } from '../settings/settings';
import { UpcomingPage } from '../upcoming/upcoming';
import { LibraryPage } from '../library/library';
import { DevPage } from '../dev/dev';
import { Constants } from '../../app/models/constants.model';
import { CacheService } from '../../app/services/cache.service';

@Component({
  selector: 'page-tabs',
  templateUrl: 'tabs.html'
})
export class TabsPage {
  @ViewChild('tabs') tabs: Content;

  tabEpisodes = ShowsPage;
  tabLibrary = LibraryPage;
  tabHighlights = HighlightsPage;
  tabUpcoming = UpcomingPage;
  tabConnect = ConnectPage;
  tabSettings = SettingsPage;
  tabDev = DevPage;

  private TAB_TITLE_EPISODES: string = 'Episodes';
  private TAB_TITLE_LIBRARY: string = 'My Library';
  private TAB_TITLE_HIGHLIGHTS: string = 'Highlights';
  private TAB_TITLE_UPCOMING: string = 'Upcoming';
  private TAB_TITLE_CONNECT: string = 'Connect';
  private TAB_TITLE_SETTINGS: string = 'Settings';
  private TAB_TITLE_DEV: string = 'Dev';

  private liveText: string = '';
  private isDevModeActive: boolean = false;

  constructor(
    private showService: ShowService,
    private loggerService: LoggerService,
    private storage: CacheService,
    private ref: ChangeDetectorRef
  ) {
    // this lets us know if our live show is currently active.
    this.showService.showLiveStatus.subscribe((status) => {
      status ? (this.liveText = 'LIVE') : (this.liveText = '');
    });

    this.updateIsDevModeActive();
  }

  private updateIsDevModeActive() {
    this.storage.get('isDevModeActive').then((isDevModeActive) => {
      this.isDevModeActive = isDevModeActive;
    });
  }

  // the main function I want to test
  logEvent(event): void {
    let action = '';
    switch (event.tabTitle) {
      case this.TAB_TITLE_EPISODES:
        action = Constants.EVENTS.LOG.MENU_EPISODES_TAP;
        break;
      case this.TAB_TITLE_LIBRARY:
        action = Constants.EVENTS.LOG.MENU_LIBRARY_TAP;
        break;
      case this.TAB_TITLE_HIGHLIGHTS:
        action = Constants.EVENTS.LOG.MENU_HIGHLIGHTS_TAP;
        break;
      case this.TAB_TITLE_UPCOMING:
        action = Constants.EVENTS.LOG.MENU_UPCOMING_TAP;
        break;
      case this.TAB_TITLE_CONNECT:
        action = Constants.EVENTS.LOG.MENU_CONNECT_TAP;
        break;
      case this.TAB_TITLE_SETTINGS:
        action = Constants.EVENTS.LOG.MENU_SETTINGS_TAP;
        break;
    }
    this.loggerService.postEvent({
      clientAction: action
    });
  }
}

tabs.spec.ts

import { async, TestBed, ComponentFixture } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { NavController, IonicModule } from 'ionic-angular';
import { Component } from '@angular/core';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { TabsPage } from './tabs';
import { ShowService } from '../../app/services/show.service';
import { ShowServiceMock } from '../../unit-tests/mocks/show.service.mock';
import { LoggerService } from '../../app/services/logger.service';
import { LoggerServiceMock } from '../../unit-tests/mocks/logger.service.mock';
import { CacheService } from '../../app/services/cache.service';
import { CacheServiceMock } from '../../unit-tests/mocks/cache.service.mock';
import { NavMock } from '../../unit-tests/mocks/nav.mock';
import { MockComponent } from 'ng-mocks';
import { ShowsPage } from '../shows/shows';

@Component({ selector: 'mini-player', template: '' })
class MiniPlayerStubComponent { }

describe('TabsPage', () => {
  let navController: NavController;
  let showService: ShowService;
  let loggerService: LoggerService;
  let cacheService: CacheService;
  let fixture: ComponentFixture<TabsPage>;
  let instance: TabsPage;


  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        TabsPage,
        MiniPlayerStubComponent,
        MockComponent(ShowsPage)
      ],
      imports: [
        NoopAnimationsModule,
        IonicModule.forRoot(this)
      ],
      providers: [
        {
          provide: NavController, useClass: NavMock
        },
        {
          provide: ShowService,
          useClass: ShowServiceMock
        },
        {
          provide: LoggerService,
          useClass: LoggerServiceMock
        },
        {
          provide: CacheService,
          useClass: CacheServiceMock
        }
      ]
    })
      .compileComponents()
      .then(() => {
        // mock services
        navController = TestBed.get(NavController);
        showService = TestBed.get(ShowService);
        loggerService = TestBed.get(LoggerService);
        cacheService = TestBed.get(CacheService);

        // load component
        fixture = TestBed.createComponent(TabsPage);
        instance = fixture.componentInstance;
        fixture.detectChanges();
      });
  }));

  it('creates the tab page', () => {
    expect(instance).toBeTruthy();
  });
});

Все это прекрасно работает, если вы запускаете приложение с ionic serve или стелефон.Проблема возникает при попытке запустить тест для этого приложения.У меня возникла проблема при попытке макета страниц, которые импортированы на вкладках.

Я начал с запуска теста и затем разрешил ошибки по мере их появления.ShowsPage сначала ошибся, потому что пытался загрузить его.Я смоделировал его аналогично MiniPlayerStubComponent, но когда я попытался импортировать или предоставить его в TestBed, я получил: «Не найдена фабрика компонентов для« ShowsPage ». Вы добавили ее в @ NgModule.entryComponents?»

После некоторого поиска, я наткнулся на проект ng-mocks.Я добавил это в свой проект и добавил MockComponent(ShowsPage) в мои объявления в TestBed.это привело к новой ошибке: Cannot find module '@angular/animations' from 'platform-browser-animations.umd.js'

Я нашел два решения, чтобы обойти эту ошибку.Один полностью не работал, который импортировал NoopAnimationsModule и добавил это к импорту.Я сделал это в спецификации выше, но та же ошибка сохранилась.Другим решением было просто добавить его в проект.Я сделал это и ng-mocks затем выдал новую ошибку: TypeError: Cannot read property 'annotations' of undefined

Это происходит здесь:

at MockDirectiveResolver.Object.<anonymous>.DirectiveResolver.resolve (node_modules/@angular/compiler/@angular/compiler.es5.js:14349:56)
      at MockDirectiveResolver.Object.<anonymous>.MockDirectiveResolver.resolve (packages/compiler/testing/src/directive_resolver_mock.ts:49:1)
      at Object.MockComponent (node_modules/ng-mocks/lib/mock-component/mock-component.ts:24:9)
      at src/pages/tabs/tabs.spec.ts:34:9

Когда я вызываю MockComponents (ShowsPage), он пытается разрешить компонент, и этосвойства, но, очевидно, не может найти это свойство "аннотации".Я не уверен, вводится ли это свойство angular animations или как ...

Я в растерянности и мне нужно какое-то направление.Я уже столько раз пробовал, надеюсь, кто-то где-то решил эту проблему.Заранее спасибо за любую помощь!

...