MatDialog Service Unit Test Angular 6 Error

后端 未结 3 1072
长情又很酷
长情又很酷 2020-12-14 16:37

I\'m having modal service to open, confirm and close dialog and i am making its unit test file but i got and error on Angular and this is the code.

modal.ser

相关标签:
3条回答
  • 2020-12-14 16:48

    I do not have the exact answer for your case but I also did some tests on MatDialog. I can show you what I did. Maybe look at the inject() part:

    (I deleted some things for clarity and confidentiality)

    describe('MyDialogComponent', () => {
      let dialog: MatDialog;
      let overlayContainer: OverlayContainer;
      let component: MyDialogComponent;
      let fixture: ComponentFixture<MyDialogComponent>;
      const mockDialogRef = {
        close: jasmine.createSpy('close')
      };
    
      beforeEach(async(() => {
        TestBed.configureTestingModule({
          imports: [
            BrowserAnimationsModule,
            ReactiveFormsModule,
            AngularMaterialModule,
          ],
          providers: [
            { provide: MatDialogRef, useValue: mockDialogRef },
            {
              provide: MAT_DIALOG_DATA,
              useValue: {
                title: 'myTitle',
              }
            }
          ],
          declarations: [MyDialogComponent],
        });
    
        TestBed.overrideModule(BrowserDynamicTestingModule, {
          set: {
            entryComponents: [MyDialogComponent]
          }
        });
    
        TestBed.compileComponents();
      }));
    
      beforeEach(inject([MatDialog, OverlayContainer],
        (d: MatDialog, oc: OverlayContainer) => {
          dialog = d;
          overlayContainer = oc;
        })
      );
    
      afterEach(() => {
        overlayContainer.ngOnDestroy();
      });
    
      beforeEach(() => {
        fixture = TestBed.createComponent(MyDialogComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
      });
    
      it('should create', () => {
        expect(component).toBeTruthy();
      });
    
    
      it('onCancel should close the dialog', () => {
        component.onCancel();
        expect(mockDialogRef.close).toHaveBeenCalled();
      });
    
    });
    
    0 讨论(0)
  • 2020-12-14 16:52

    I have a better solution that still works on 2019

    header.component.ts

    import { BeforeLogOutComponent } from '@app-global/components/before-log-out/before-log-out.component';
    
    
      /**
       * The method triggers before the logout.
       * Opens the dialog and warns the user before log Out.
       */
      public beforeLogOut(): void {
        this._dialog.open(BeforeLogOutComponent, { width: '400px', disableClose: false, panelClass: 'dialog_before_log_out' })
        .afterClosed()
        .subscribe((res) => {
          if (res && res.action === true) { this.loggedOut(); }
        }, err => {
          console.error(err);
        });
      }
    

    header.component.spec.ts

    import { async, ComponentFixture, TestBed } from '@angular/core/testing';
    import { MatDialog } from '@angular/material';
    import { Observable, of } from 'rxjs';
    
    
    
    <<-- Create a MatDialog mock class -->>
    export class MatDialogMock {
      // When the component calls this.dialog.open(...) we'll return an object
      // with an afterClosed method that allows to subscribe to the dialog result observable.
      open() {
        return {
          afterClosed: () => of({action: true})
        };
      }
    }
    
    
    
    describe('HeaderComponent', () => {
    
      let component: HeaderComponent;
      let fixture: ComponentFixture<HeaderComponent>;
    
      beforeEach(async(() => {
    
        TestBed.configureTestingModule({
          imports: [
            MaterialModule, RouterTestingModule, HttpModule, BrowserAnimationsModule,
            HttpClientModule, FlexLayoutModule,
          ],
          declarations: [
            HeaderComponent,
          ],
          providers: [
            { provide: MatDialog, useClass: MatDialogMock } <<-- look this
          ]
        })
        .compileComponents();
      }));
    
    
    
      beforeEach(async() => {
        fixture = TestBed.createComponent(HeaderComponent);
        component = fixture.componentInstance;
    
    
        component.ngOnInit();
        component.ngAfterViewInit();
        await fixture.whenStable();
        fixture.detectChanges();
      });
    
    
      fit('should create', () => {
        expect(component).toBeTruthy();
      });
    
    
      // I test the dialog here.
      fit('should open the dialog', () => {
        component.beforeLogOut();
      });
    
    
    }
    
    0 讨论(0)
  • 2020-12-14 16:57

    Testing mat-dialogs can be tricky. I tend to use a spy object for the return from a dialog open (dialogRefSpyObj below) so I can more easily track and control tests. In your case it might look something like the following:

    describe('ModalService', () => {
        let modalService: ModalService;
        let dialogSpy: jasmine.Spy;
        let dialogRefSpyObj = jasmine.createSpyObj({ afterClosed : of({}), close: null });
        dialogRefSpyObj.componentInstance = { body: '' }; // attach componentInstance to the spy object...
    
        beforeEach(() => {
            TestBed.configureTestingModule({
                imports: [MatDialogModule],
                providers: [ModalService]
            });
            modalService = TestBed.get(ModalService);
        });
    
        beforeEach(() => {
            dialogSpy = spyOn(TestBed.get(MatDialog), 'open').and.returnValue(dialogRefSpyObj);
        });
    
        it('open modal ', () => {
            modalService.open(TestComponent, '300px');
            expect(dialogSpy).toHaveBeenCalled();
    
            // You can also do things with this like:
            expect(dialogSpy).toHaveBeenCalledWith(TestComponent, { maxWidth: '100vw' });
    
            // and ...
            expect(dialogRefSpyObj.afterClosed).toHaveBeenCalled();
        });
    });
    
    0 讨论(0)
提交回复
热议问题