如何使用属性模拟 MAT_DIALOG_DATA

How to mock MAT_DIALOG_DATA with properties

我需要测试具有 MAT_DIALOG_DATA 的组件,我什至可以模拟它,但我对数据接收的属性有疑问。

我相信模拟是正确的,但我不知道如何将属性放在变量数据上。

*通知-edit.component.spec.ts

fdescribe('NotificationsEditComponent', () => {
  let component: NotificationsEditComponent;
  let fixture: ComponentFixture<NotificationsEditComponent>;
  let dialogMock: jasmine.SpyObj<any>;
  let dialogRefMock: jasmine.SpyObj<any>;
  
  beforeEach(waitForAsync(() => {

    dialogRefMock = jasmine.createSpyObj('MatDialogRef', [
      'close',
    ]);

    TestBed.configureTestingModule({
      imports: [
        CommonModule,
        ReactiveFormsModule,
        FormsModule,
        AppModule,
        MatDialogModule,
        MatFormFieldModule,
        MatInputModule,
      ],
      declarations: [ NotificationsEditComponent ],
      providers: [
        { provide: MatDialogRef, useValue: dialogMock },
        { provide: MAT_DIALOG_DATA, useValue: {} },
      ]
    })
    .compileComponents();
  }));

*通知-edit.component.ts

  constructor(
    public dialog: MatDialog,
    public dialogRef: MatDialogRef<NotificationsEditComponent>,
    @Inject(MAT_DIALOG_DATA) public notification: any
  ) {}

  ngOnInit() {
    this.form = new FormGroup({
      frequency: new FormControl(),
      topic: new FormControl(),
      title: new FormControl(),
      time: new FormControl(),
      day: new FormControl(),
      body: new FormControl()
    })
    this.form.setValue({
      frequency: this.notification.frequency,
      topic: this.notification.topic,
      title: this.notification.payload.notification.title,
      time: this.notification.time.seconds,
      day: this.notification.day.day,
      body: this.notification.payload.notification.body
    })
  }

错误

TypeError: Cannot read property 'notification' of undefined
    at NotificationsEditComponent.ngOnInit (http://localhost:9876/_karma_webpack_/webpack:/src/app/modules/notifications/pages/notifications-edit/notifications-edit.component.ts:108:23)
    at callHook (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2015/core.js:2521:1)
    at callHooks (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2015/core.js:2492:1)
    at executeInitAndCheckHooks (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2015/core.js:2443:1)
    at refreshView (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2015/core.js:9429:1)
    at renderComponentOrTemplate (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2015/core.js:9528:1)
    at tickRootContext (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2015/core.js:10754:1)
    at detectChangesInRootView (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2015/core.js:10779:1)
    at RootViewRef.detectChanges (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2015/core.js:22792:1)
    at ComponentFixture._tick (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/fesm2015/testing.js:141:1)

您是否厌倦了为您的 MAT_DIALOG_DATA 创建模拟? 如我所见,您需要一些属性,因此您应该试一试

const notificationMock = {
  frequency: yourmockvalue,
  topic: yourmockvalue,
  payload: {
   notification: {
      title: yourmockvalue,
      body: yourmockvalue
   }
  },
  time: {
    seconds: yourmockvalue
  },
  day: {
    day: yourmockvalue
  },
}

对于第一个猜测,我认为您的组件收到一个 {} 作为模拟,这就是它无法从中读取属性的原因。

现在您可以在测试设置中使用了。

{ provide: MAT_DIALOG_DATA, useValue: notificationMock }

你能试试这样模拟吗?

我最后的建议:在读取属性时在 ngOninit 上使用 ? 运算符,因为在生产中,如果没有收到正确的 MAT_DIALOG_DATA,您的代码将以与现在相同的方式中断.

Elvis operator