为什么 store.dispatch() 没有在订阅块中被调用?

Why isn't store.dispatch() getting called in the subscribe block?

所以我有一个 MatDialog Box,它在关闭时发送一些表单值。然后我在 MatDialogRef 提供的 afterClosed 方法中调度一个动作。

当我手动测试它时,它工作得很好。但是在单元测试时,没有调用调度,我的测试失败了。

我的代码在打开对话框时运行并在关闭时调度操作。

openAddUserDialog() {
     this.addUserDialog = this.dialog.open(AddUserDialogComponent, {
      width: 'max-content',
      height: 'max-content',
      minWidth: '35vw',
      minHeight: '20vh',
      autoFocus: false
    });

     this.addUserDialog.afterClosed().subscribe(result => {
      console.log(result);
      this.store.dispatch({type: UserActions.ActionTypes.TryAddUser, payload: result.value});
    });
  }

MatDialog 的模拟

export class MatDialogMock {
  open() {
    return {
      afterClosed: () => of(initialValue)
    };
  }
}

测试台配置

 beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [MaterialModule, ReactiveFormsModule, BrowserAnimationsModule],
      declarations: [ UserManagementDialogComponent ],
      providers: [{provide: MatDialog, useClass: MatDialogMock}, provideMockStore({initialState})]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(UserManagementDialogComponent);
    component = fixture.componentInstance;

    store = TestBed.get(Store);
    spyOn(store, 'dispatch').and.callThrough();
    dialog = TestBed.get(MatDialog);

    fixture.detectChanges();
  });

以及应该通过的测试

it('should dispatch an action when the form is submitted', fakeAsync(() => {

    spyOn(dialog, 'open').and.callThrough();
    const dialogRef = dialog.open();

    dialogRef.afterClosed().subscribe(result => {
      console.log('verbrberbhyn', result);
      expect(result).toEqual(initialValue);

      tick();

      expect(store.dispatch).toHaveBeenCalledTimes(1);
      expect(store.dispatch).toHaveBeenCalledWith({
        type: UserAtions.ActionTypes.TryAddUser,
        payload: initialValue
      });
    });
  }));

找到我无法通过测试用例的原因了。

afterClosed() 在对话框关闭后被调用。所以我所要做的就是在订阅 afterClosed()

之前调用 dialog.close()

所以最后我的测试函数看起来像:

it('should dispatch an action when the form is submitted', () => {

    spyOn(dialog, 'open').and.callThrough();
    component.openAddUserDialog();
    dialog.close();
    component.addUserDialog.afterClosed().subscribe(result => {

      expect(result.value).toEqual(initialValue);
      expect(store.dispatch).toHaveBeenCalledTimes(1);
      expect(store.dispatch).toHaveBeenCalledWith({
        type: UserAtions.ActionTypes.TryAddUser,
        payload: result.value
      });
    });
  });

而且我还更新了 Mock

export class MatDialogMock {
  open() {
    return {
      afterClosed: () => of({value: initialValue})
    };
  }

  close() {}
}

以便在模拟对话框中调用 close() 并更新 afterClosed(),因为操作的有效负载存储在值 属性:

this.addUserDialog.afterClosed().subscribe(result => {
      console.log(result);
      this.store.dispatch({type: UserActions.ActionTypes.TryAddUser, payload: result.value});
    });