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

时间:2019-03-20 23:14:17

标签: angular jasmine angular-material2 ngrx ngrx-store-4.0

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

当我手动测试它时,效果很好。但是在进行单元测试时,没有调用调度,并且我的测试失败了。

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

 SELECT 
     g.RECORD_ID, g.RECORD_CREATED_DATE, g.lastUpdateDate, t.RECORD_STATUS_CODE
 FROM 
    ( 
        SELECT RECORD_ID, MIN(RECORD_CREATED_DATE) AS RECORD_CREATED_DATE, MAX(RECORD_UPDATED_DATE) AS lastUpdateDate 
            FROM DB.RECORD
            GROUP BY RECORD_ID
    ) g
    JOIN DB.RECORD t ON g.RECORD_ID = t.RECORD_ID and g.lastUpdateDate = t.RECORD_UPDATED_DATE
 ORDER BY RECORD_ID

MatDialog的模拟

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});
    });
  }

TestBed配置

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();
  });

1 个答案:

答案 0 :(得分:0)

找出为什么我无法通过测试用例。

对话框关闭后,

afterClosed()被调用。因此,我要做的就是在订阅dialog.close()

之前先致电afterClosed()

所以最后我的测试功能如下:

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
      });
    });
  });

我还更新了模拟游戏

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

  close() {}
}

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

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