私はangularの開発が初めてで、ジャスミンを使用した単体テストの方が新しいです。 @ angular/materialからangular material MatDialogRef、MAT_DIALOG_DATAを使用してダイアログをsoくコンポーネントを作成しました。コンポーネントは正常に機能していますが、ユニットテストでエラーが発生し、解決できません。
私はこれが機能するために本当に必要であり、どんな助けも感謝します....事前に感謝します.. !!!
以下の私のコードを見つけてください:
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { HttpClientModule, HttpClient } from '@angular/common/http';
import { HttpModule } from '@angular/http';
import { RouterModule, Routes } from '@angular/router';
import 'hammerjs';
import { NgxPhoneSelectModule } from 'ngx-phone-select';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatInputModule, MatButtonModule, MatSelectModule } from '@angular/material';
import { MatGridListModule } from '@angular/material';
import { MatTableModule } from '@angular/material';
import { MatDialogModule} from '@angular/material';
import { MatCardModule} from '@angular/material';
import { MaterialModule } from './modules/material/material.module';
import { AppComponent } from './app.component';
import { CustomerComponent } from './components/customer/customer.component';
import { LoginComponent } from './components/login/login.component';
import { ForgetPasswordComponent } from './components/forget-password/forget-password.component';
import { PageNotFoundComponent } from './components/page-not-found/page-not-found.component';
import { DashboardComponent } from './components/dashboard/dashboard.component';
import { LoaderService } from './services/loader.service';
import { CustomerDataService } from './services/customer-data.service';
import { UserService } from './services/user/user.service';
import { HeaderComponent } from './components/header/header.component';
import { UpdateCustomerComponent } from './components/update-customer/update-customer.component';
import { AuthService } from './services/auth.service';
import { AuthGuard } from './services/auth/auth.guard';
import { DeleteCustomerComponent } from './components/delete-customer/delete-customer.component';
import { FooterComponent } from './components/footer/footer.component';
const appRoutes: Routes = [
{
path: '',
component: LoginComponent
},
{
path: 'create-customer',
component: CustomerComponent,
// canActivate: [AuthGuard] // ristrict direct access of links
},
{
path: 'forget-password',
component: ForgetPasswordComponent,
// canActivate: [AuthGuard] // ristrict direct access of links
},
{
path: 'dashboard',
component: DashboardComponent,
// canActivate: [AuthGuard] // ristrict direct access of links
},
{
path: 'update-customer',
component: UpdateCustomerComponent,
// canActivate: [AuthGuard] // ristrict direct access of links
},
{
path: '**',
component: PageNotFoundComponent
}
];
@NgModule({
declarations: [
AppComponent,
CustomerComponent,
LoginComponent,
ForgetPasswordComponent,
PageNotFoundComponent,
DashboardComponent,
HeaderComponent,
UpdateCustomerComponent,
DeleteCustomerComponent,
FooterComponent
],
imports: [
BrowserModule,
HttpClientModule,
HttpModule,
RouterModule.forRoot(appRoutes),
NgxPhoneSelectModule,
BrowserAnimationsModule,
FormsModule,
ReactiveFormsModule,
MatInputModule,
MatButtonModule,
MatSelectModule,
MatGridListModule,
MatTableModule,
MaterialModule
],
entryComponents: [
DeleteCustomerComponent
],
schemas: [ CUSTOM_ELEMENTS_SCHEMA ],
providers: [LoaderService, AuthService, AuthGuard, UserService, CustomerDataService],
bootstrap: [AppComponent]
})
export class AppModule { }
顧客コンポーネントの削除
import { Component, OnInit, Inject } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
import { Router} from '@angular/router';
@Component({
selector: 'app-delete-customer',
templateUrl: './delete-customer.component.html',
styleUrls: ['./delete-customer.component.scss']
})
export class DeleteCustomerComponent implements OnInit {
constructor(private router: Router, public deleteCustDialogRef: MatDialogRef<DeleteCustomerComponent>, @Inject(MAT_DIALOG_DATA) public data: string) { }
ngOnInit() {
}
onClosedeleteCustomer() {
this.deleteCustDialogRef.close('confirm');
this.router.navigate(['./dashboard']);
}
onCloseCancel() {
this.deleteCustDialogRef.close('cancel');
}
}
delete-customer.component.spec.ts
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import {RouterTestingModule} from '@angular/router/testing';
import { DeleteCustomerComponent } from './delete-customer.component';
import { MaterialModule } from '../../modules/material/material.module';
import { MatDialogRef, MAT_DIALOG_DATA, MatDialog, MatDialogModule } from '@angular/material';
describe('DeleteCustomerComponent', () => {
let component: DeleteCustomerComponent;
let fixture: ComponentFixture<DeleteCustomerComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ DeleteCustomerComponent ],
imports: [ MaterialModule, RouterTestingModule, MatDialogModule ],
providers : [ MatDialogRef, MAT_DIALOG_DATA, MatDialog ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(DeleteCustomerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
カルマエラー
DeleteCustomerComponent should create
Failed: Can't resolve all parameters for MatDialogRef: (?, ?, ?).
Error: Can't resolve all parameters for MatDialogRef: (?, ?, ?).
at syntaxError (http://localhost:9876/_karma_webpack_/webpack:/C:/dewatering_FST/node_modules/@angular/compiler/esm5/compiler.js:485:22)
at CompileMetadataResolver.webpackJsonp.../../../compiler/esm5/compiler.js.CompileMetadataResolver._getDependenciesMetadata (http://localhost:9876/_karma_webpack_/webpack:/C:/dewatering_FST/node_modules/@angular/compiler/esm5/compiler.js:15662:1)
at CompileMetadataResolver.webpackJsonp.../../../compiler/esm5/compiler.js.CompileMetadataResolver._getTypeMetadata (http://localhost:9876/_karma_webpack_/webpack:/C:/dewatering_FST/node_modules/@angular/compiler/esm5/compiler.js:15497:1)
at CompileMetadataResolver.webpackJsonp.../../../compiler/esm5/compiler.js.CompileMetadataResolver._getInjectableMetadata (http://localhost:9876/_karma_webpack_/webpack:/C:/dewatering_FST/node_modules/@angular/compiler/esm5/compiler.js:15477:1)
at CompileMetadataResolver.webpackJsonp.../../../compiler/esm5/compiler.js.CompileMetadataResolver.getProviderMetadata (http://localhost:9876/_karma_webpack_/webpack:/C:/dewatering_FST/node_modules/@angular/compiler/esm5/compiler.js:15837:1)
at http://localhost:9876/_karma_webpack_/webpack:/C:/dewatering_FST/node_modules/@angular/compiler/esm5/compiler.js:15748:1
at Array.forEach (<anonymous>)
at CompileMetadataResolver.webpackJsonp.../../../compiler/esm5/compiler.js.CompileMetadataResolver._getProvidersMetadata (http://localhost:9876/_karma_webpack_/webpack:/C:/dewatering_FST/node_modules/@angular/compiler/esm5/compiler.js:15708:1)
at CompileMetadataResolver.webpackJsonp.../../../compiler/esm5/compiler.js.CompileMetadataResolver.getNgModuleMetadata (http://localhost:9876/_karma_webpack_/webpack:/C:/dewatering_FST/node_modules/@angular/compiler/esm5/compiler.js:15276:1)
at JitCompiler.webpackJsonp.../../../compiler/esm5/compiler.js.JitCompiler._loadModules (http://localhost:9876/_karma_webpack_/webpack:/C:/dewatering_FST/node_modules/@angular/compiler/esm5/compiler
ダイアログコンポーネントをテストしようとしたときに、同じ問題が発生しました。私のソリューションは、角度材料のソースコードの dialog test に基づいています。
import { MyDialogComponent } from './mydialog.component';
import { async, TestBed, inject } from '@angular/core/testing';
import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { MatDialog } from '@angular/material/dialog';
import { OverlayContainer } from '@angular/cdk/overlay';
describe('MyDialogComponent', () => {
let dialog: MatDialog;
let overlayContainer: OverlayContainer;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [MyDialogComponent],
imports: [
MatDialogModule,
]
});
TestBed.overrideModule(BrowserDynamicTestingModule, {
set: {
entryComponents: [MyDialogComponent]
}
});
TestBed.compileComponents();
}));
beforeEach(inject([MatDialog, OverlayContainer],
(d: MatDialog, oc: OverlayContainer) => {
dialog = d;
overlayContainer = oc;
})
);
afterEach(() => {
overlayContainer.ngOnDestroy();
});
it('should open a dialog with a component', () => {
const dialogRef = dialog.open(MyDialogComponent, {
data: { param: '1' }
});
// verify
expect(dialogRef.componentInstance instanceof MyDialogComponent).toBe(true);
});
});
しかし、これが正しいアプローチであるかどうかはわかりませんが、まだ初心者です。
ニーズに応じて、より簡単なアプローチは、closeメソッドまたはopenメソッド用のジャスミンスパイを持つ模擬MatDialogプロバイダーを注入することです。例えば:
import { MyDialogComponent } from './mydialog.component';
import { async, TestBed, inject } from '@angular/core/testing';
import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing';
import { MatDialog } from '@angular/material/dialog';
describe('MyDialogComponent', () => {
const mockDialogRef = {
close: jasmine.createSpy('close')
};
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [MyDialogComponent],
imports: [MatDialogModule],
providers: [
{
provide: MatDialogRef,
useValue: mockDialogRef
}
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MyDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('#onClosedeleteCustomer should close the dialog', () => {
component.onClosedeleteCustomer();
expect(mockDialogRef.close).toHaveBeenCalled();
});
});
このGistは、テストにMatDialogまたはMatDialogRefの実際のインスタンスを挿入しないでください。メソッドが呼び出されたかどうかを伝えることができるジャスミンスパイを代わりにモックオブジェクトに注入します。