From afa33a5a00aed2c0bc03292765f9c83a2081c3d7 Mon Sep 17 00:00:00 2001 From: Robin Genz Date: Thu, 7 Jan 2021 14:32:48 +0100 Subject: [PATCH] test: implement SharedTestingModule (#75) --- angular.json | 5 +++++ karma.conf.js | 2 +- src/app/app.component.spec.ts | 13 ++++++++----- .../core/services/dialog/dialog.service.spec.ts | 4 ++-- .../semester-gpa-bar.component.spec.ts | 4 ++-- .../semester-select.component.spec.ts | 4 ++-- .../unit-card/unit-card.component.spec.ts | 3 ++- .../pages/exam-results/exam-results.page.spec.ts | 13 ++++++++----- .../modules/login/pages/login/login.page.spec.ts | 5 ++--- src/test.ts | 3 ++- src/tests/mocks/angular-mocks.ts | 16 ++++++++++++++++ src/tests/mocks/index.ts | 1 + src/tests/modules/index.ts | 1 + src/tests/modules/shared-testing.module.ts | 11 +++++++++++ src/tests/test-setup.ts | 14 ++++++++++++++ 15 files changed, 77 insertions(+), 22 deletions(-) create mode 100644 src/tests/mocks/angular-mocks.ts create mode 100644 src/tests/mocks/index.ts create mode 100644 src/tests/modules/index.ts create mode 100644 src/tests/modules/shared-testing.module.ts diff --git a/angular.json b/angular.json index 7c0c2fd..dbc93e1 100644 --- a/angular.json +++ b/angular.json @@ -109,6 +109,11 @@ "glob": "**/*", "input": "src/assets", "output": "/assets" + }, + { + "glob": "**/*.svg", + "input": "node_modules/ionicons/dist/ionicons/svg", + "output": "./svg" } ] }, diff --git a/karma.conf.js b/karma.conf.js index 5ad280b..036ae49 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -22,7 +22,7 @@ module.exports = function (config) { // or set a specific seed with `seed: 4321` }, clearContext: false, // leave Jasmine Spec Runner output visible in browser - captureConsole: false, + captureConsole: true, }, jasmineHtmlReporter: { suppressAll: true, // removes the duplicated traces diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index 9e6a90d..15b9fa9 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -1,7 +1,8 @@ -import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; import { Plugins, SplashScreenPlugin, StatusBarPlugin, StatusBarStyle } from '@capacitor/core'; -import { Platform } from '@ionic/angular'; +import { NavController, Platform } from '@ionic/angular'; +import { SharedTestingModule } from '@tests/modules'; import { createPlatformSpy } from '@tests/spies'; import { AppComponent } from './app.component'; @@ -19,13 +20,15 @@ describe('AppComponent', () => { originalStatusBar = Plugins.StatusBar; Plugins.StatusBar = jasmine.createSpyObj('StatusBarPlugin', ['setOverlaysWebView', 'setStyle']); Plugins.SplashScreen = jasmine.createSpyObj('SplashScreenPlugin', ['hide']); - platformSpy = createPlatformSpy(); TestBed.configureTestingModule({ declarations: [AppComponent], - schemas: [CUSTOM_ELEMENTS_SCHEMA], - providers: [{ provide: Platform, useValue: platformSpy }], + imports: [SharedTestingModule, RouterTestingModule], + providers: [ + { provide: Platform, useValue: platformSpy }, + { provide: NavController, useValue: {} }, + ], }).compileComponents(); fixture = TestBed.createComponent(AppComponent); diff --git a/src/app/core/services/dialog/dialog.service.spec.ts b/src/app/core/services/dialog/dialog.service.spec.ts index 20651c0..11811fb 100644 --- a/src/app/core/services/dialog/dialog.service.spec.ts +++ b/src/app/core/services/dialog/dialog.service.spec.ts @@ -2,11 +2,11 @@ import { TestBed } from '@angular/core/testing'; import { AlertController, AngularDelegate, - IonicModule, LoadingController, ModalController, PopoverController, } from '@ionic/angular'; +import { SharedTestingModule } from '@tests/modules'; import { DialogService } from './dialog.service'; describe('DialogService', () => { @@ -28,7 +28,7 @@ describe('DialogService', () => { { provide: LoadingController, useValue: loadingControllerSpy }, { provide: PopoverController, useValue: popoverControllerSpy }, ], - imports: [IonicModule], + imports: [SharedTestingModule], }); service = TestBed.inject(DialogService); }); diff --git a/src/app/modules/exam-results/components/semester-gpa-bar/semester-gpa-bar.component.spec.ts b/src/app/modules/exam-results/components/semester-gpa-bar/semester-gpa-bar.component.spec.ts index c148cdc..25c4495 100644 --- a/src/app/modules/exam-results/components/semester-gpa-bar/semester-gpa-bar.component.spec.ts +++ b/src/app/modules/exam-results/components/semester-gpa-bar/semester-gpa-bar.component.spec.ts @@ -1,5 +1,5 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { IonicModule } from '@ionic/angular'; +import { SharedTestingModule } from '@tests/modules'; import { SemesterGpaBarComponent } from './semester-gpa-bar.component'; describe('SemesterGpaBarComponent', () => { @@ -11,7 +11,7 @@ describe('SemesterGpaBarComponent', () => { waitForAsync(() => { TestBed.configureTestingModule({ declarations: [SemesterGpaBarComponent], - imports: [IonicModule.forRoot()], + imports: [SharedTestingModule], }).compileComponents(); fixture = TestBed.createComponent(SemesterGpaBarComponent); diff --git a/src/app/modules/exam-results/components/semester-select/semester-select.component.spec.ts b/src/app/modules/exam-results/components/semester-select/semester-select.component.spec.ts index 24d4815..b11970a 100644 --- a/src/app/modules/exam-results/components/semester-select/semester-select.component.spec.ts +++ b/src/app/modules/exam-results/components/semester-select/semester-select.component.spec.ts @@ -1,6 +1,6 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { IonicModule } from '@ionic/angular'; import { SelectChangeEventDetail } from '@ionic/core'; +import { SharedTestingModule } from '@tests/modules'; import { SemesterListItem } from '../../interfaces'; import { SemesterSelectComponent } from './semester-select.component'; @@ -13,7 +13,7 @@ describe('SemesterSelectComponent', () => { waitForAsync(() => { TestBed.configureTestingModule({ declarations: [SemesterSelectComponent], - imports: [IonicModule.forRoot()], + imports: [SharedTestingModule], }).compileComponents(); fixture = TestBed.createComponent(SemesterSelectComponent); diff --git a/src/app/modules/exam-results/components/unit-card/unit-card.component.spec.ts b/src/app/modules/exam-results/components/unit-card/unit-card.component.spec.ts index 9638d06..a6dd330 100644 --- a/src/app/modules/exam-results/components/unit-card/unit-card.component.spec.ts +++ b/src/app/modules/exam-results/components/unit-card/unit-card.component.spec.ts @@ -1,5 +1,6 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { IonicModule } from '@ionic/angular'; +import { SharedTestingModule } from '@tests/modules'; import { EmptyStringPipe } from '../../pipes'; import { UnitCardComponent } from './unit-card.component'; @@ -12,7 +13,7 @@ describe('UnitCardComponent', () => { waitForAsync(() => { TestBed.configureTestingModule({ declarations: [UnitCardComponent, EmptyStringPipe], - imports: [IonicModule.forRoot()], + imports: [SharedTestingModule], }).compileComponents(); fixture = TestBed.createComponent(UnitCardComponent); diff --git a/src/app/modules/exam-results/pages/exam-results/exam-results.page.spec.ts b/src/app/modules/exam-results/pages/exam-results/exam-results.page.spec.ts index dac7084..cc17d09 100644 --- a/src/app/modules/exam-results/pages/exam-results/exam-results.page.spec.ts +++ b/src/app/modules/exam-results/pages/exam-results/exam-results.page.spec.ts @@ -1,8 +1,9 @@ -import { ChangeDetectorRef, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { ChangeDetectorRef } from '@angular/core'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { Router } from '@angular/router'; import { AuthenticationService, DialogService } from '@app/core'; -import { IonicModule } from '@ionic/angular'; +import { createComponentMock } from '@tests/mocks'; +import { SharedTestingModule } from '@tests/modules'; import { ExamResultsPageService } from '../../services'; import { ExamResultsPage } from './exam-results.page'; @@ -33,9 +34,11 @@ describe('ExamResultsPage', () => { ]); TestBed.configureTestingModule({ - declarations: [ExamResultsPage], - schemas: [CUSTOM_ELEMENTS_SCHEMA], - imports: [IonicModule.forRoot()], + declarations: [ + ExamResultsPage, + createComponentMock({ selector: 'app-semester-select', inputs: ['semesterList'] }), + ], + imports: [SharedTestingModule], providers: [ { provide: DialogService, useValue: dialogServiceSpy }, { provide: AuthenticationService, useValue: authServiceSpy }, diff --git a/src/app/modules/login/pages/login/login.page.spec.ts b/src/app/modules/login/pages/login/login.page.spec.ts index 48b9bc3..7f18b3b 100644 --- a/src/app/modules/login/pages/login/login.page.spec.ts +++ b/src/app/modules/login/pages/login/login.page.spec.ts @@ -1,8 +1,7 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; import { Router } from '@angular/router'; import { AuthenticationService, DialogService } from '@app/core'; -import { IonicModule } from '@ionic/angular'; +import { SharedTestingModule } from '@tests/modules'; import { LoginPage } from './login.page'; describe('LoginPage', () => { @@ -21,7 +20,7 @@ describe('LoginPage', () => { TestBed.configureTestingModule({ declarations: [LoginPage], - imports: [IonicModule.forRoot(), ReactiveFormsModule], + imports: [SharedTestingModule], providers: [ { provide: DialogService, useValue: dialogServiceSpy }, { provide: AuthenticationService, useValue: authenticationServiceSpy }, diff --git a/src/test.ts b/src/test.ts index 48c59f1..8715569 100644 --- a/src/test.ts +++ b/src/test.ts @@ -3,7 +3,7 @@ import 'zone.js/dist/zone-testing'; // Must be the FIRST import! import { getTestBed } from '@angular/core/testing'; import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; -import { improveChangeDetection } from '@tests/test-setup'; +import { improveChangeDetection, muteIonicReInitializeWarning } from '@tests/test-setup'; declare const require: any; @@ -15,3 +15,4 @@ const context = require.context('./', true, /\.spec\.ts$/); context.keys().map(context); improveChangeDetection(); +muteIonicReInitializeWarning(); diff --git a/src/tests/mocks/angular-mocks.ts b/src/tests/mocks/angular-mocks.ts new file mode 100644 index 0000000..097b305 --- /dev/null +++ b/src/tests/mocks/angular-mocks.ts @@ -0,0 +1,16 @@ +import { Component, Pipe } from '@angular/core'; + +export function createPipeMock(options: Pipe): Pipe { + const metadata: Pipe = { + name: options.name, + }; + return Pipe(metadata)(class MockPipe {}) as Pipe; +} + +export function createComponentMock(options: Component): Component { + const metadata: Component = { + selector: options.selector, + inputs: options.inputs, + }; + return Component(metadata)(class MockComponent {}) as Component; +} diff --git a/src/tests/mocks/index.ts b/src/tests/mocks/index.ts new file mode 100644 index 0000000..7578f2e --- /dev/null +++ b/src/tests/mocks/index.ts @@ -0,0 +1 @@ +export * from './angular-mocks'; diff --git a/src/tests/modules/index.ts b/src/tests/modules/index.ts new file mode 100644 index 0000000..651a3e2 --- /dev/null +++ b/src/tests/modules/index.ts @@ -0,0 +1 @@ +export * from './shared-testing.module'; diff --git a/src/tests/modules/shared-testing.module.ts b/src/tests/modules/shared-testing.module.ts new file mode 100644 index 0000000..9e436c9 --- /dev/null +++ b/src/tests/modules/shared-testing.module.ts @@ -0,0 +1,11 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { IonicModule } from '@ionic/angular'; + +@NgModule({ + imports: [CommonModule, FormsModule, ReactiveFormsModule, IonicModule.forRoot()], + declarations: [], + exports: [CommonModule, FormsModule, ReactiveFormsModule, IonicModule], +}) +export class SharedTestingModule {} diff --git a/src/tests/test-setup.ts b/src/tests/test-setup.ts index 33a8b64..d549d68 100644 --- a/src/tests/test-setup.ts +++ b/src/tests/test-setup.ts @@ -19,3 +19,17 @@ export const improveChangeDetection = () => { return componentFixture; }; }; + +// Source: https://github.com/ionic-team/ionic-framework/issues/19926#issuecomment-724188621 + +export const muteIonicReInitializeWarning = () => { + const originalWarn = console.warn; + const patchedWarn = (warning: any, ...optionalParams: any[]) => { + const suppress = `Ionic Angular was already initialized. Make sure IonicModule.forRoot() is just called once.`; + if (warning === suppress) { + return; + } + originalWarn(warning, ...optionalParams); + }; + console.warn = patchedWarn; +};