У меня есть проект, который использует 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 или как ...
Я в растерянности и мне нужно какое-то направление.Я уже столько раз пробовал, надеюсь, кто-то где-то решил эту проблему.Заранее спасибо за любую помощь!