为什么 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});
});
所以我有一个 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});
});