gpt4 book ai didi

angular - dialogRef.afterClosed 不是一个函数

转载 作者:行者123 更新时间:2023-12-02 16:36:12 34 4
gpt4 key购买 nike

您好,我正在进行单元测试并尝试覆盖我的订阅。但是它一直失败并出现错误dialogRef.afterClosed is not a function

我不确定我可以监视什么或如何监视 afterClosed() 函数,但这是我似乎无法涵盖的唯一部分。 ...

import { MatDialog } from '@angular/material/dialog';
....
constructor( private dialog: MatDialog) { }

showLogin(): void {

const dialogRef = this.dialog.open(LoginDialogComponent, {
width: '400px',
height: 'auto',
data: this.loginContext
});

dialogRef.afterClosed().subscribe(result => {
if (this.loginContext.loggedIn) {
this.showApply();
}
});
}

这是LoginDialogComponent

 ....

@Component({
selector: 'app-login-dialog',
templateUrl: './login-dialog.component.html',
styleUrls: ['./login-dialog.component.scss']
})
export class LoginDialogComponent implements OnInit {

constructor(
private authService: AuthService,
private alertService: AlertService,
public dialogRef: MatDialogRef<LoginState>,
@Inject(MAT_DIALOG_DATA) public data: LoginState) { }

ngOnInit() {
this.data.loggedIn = false;
}

login(loginEvent: LoginEvent): void {


this.authService.login(loginData).then(
resp => {
this.data.loggedIn = true; // feedback
this.dialogRef.close();
},
err => {
this.alertService.showAlert(err);
}
);
}

}

最佳答案

我将 Sam Tsai 的答案更进一步,并创建了一个 stub 文件以使其更加简洁。这是 stub 文件内容:

import { of } from 'rxjs';

/*
The default behavior is to test that the user clicked 'OK' in the dialog.
To reset to this behavior (if you've previously tested 'Cancel'),
call setResult(true).

If you want to test that the user clicked 'Cancel' in the dialog,
call setResult(false).
*/

export class MatDialogStub {
result: boolean = true;

setResult(val: boolean) {
this.result = val;
}

open() {
return {afterClosed: () => of(this.result) };
}
}

然后在 .spec.ts 文件中使用如下所示的 stub :

import { MatDialogStub } from '../../../../testing/mat-dialog-stub'; // <--- (import here)

describe('MyComponent', () => {
let component: MyComponent;
let fixture: ComponentFixture<MyComponent>;
const dialogStub = new MatDialogStub(); // <--- (declare here)

beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [],
declarations: [ MyComponent ],
providers: [
{ provide: MatDialog, useValue: dialogStub } // <--- (use here)
]
})
.compileComponents();
}));
//...
});

并且在实际测试中可以通过调用setResult()函数将返回值设置为true或false来分别模拟点击“确定”或“取消”按钮:

dialogStub.setResult(true); 

dialogStub.setResult(false);

注意: stub 测试的默认值是“OK”,因此如果您只是测试“OK”,则不必调用该函数。

下面的测试首先模拟“取消”,然后单击“确定”按钮:

it(`should not call 'delete' when Submit button pressed and user cancels`, async(() => {
component.apis = [new Api({name: 'abc'})];
component.displayPermissions = [new Permission({name: 'abc'})];
dialogStub.setResult(false); // <--- (call the function here)
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
compiled.querySelector('button').click();
expect(permissionService.delete.calls.count()).toBe(0, 'no calls');
}));

it(`should call 'delete' once when Submit button pressed and not cancelled`, async(() => {
component.apis = [new Api({name: 'abc'})];
component.displayPermissions = [new Permission({name: 'abc'})];
dialogStub.setResult(true); // <--- (call the function here)
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
compiled.querySelector('button').click();
expect(permissionService.delete.calls.count()).toBe(1, 'one call');
}));
<小时/>

原始答案

我到处寻找一种简洁的方法来模拟 MatDialog 并消除我遇到的错误dialogRef.afterClosed is not a function。 (请参阅我在底部尝试过的一些链接)。在我尝试 Sam Tsai 对这个问题的回答之前,我发现没有什么是正确的解决方案。这是一个简单的解决方案,消除了我的所有错误,并使我能够正确测试我的应用程序。我希望在花这么多时间在所有其他链接上之前找到这个。

这是失败的单元测试;它在 ('button').click 事件上失败,因为它打开 MatDialog 并且仅在对话框返回 true 时才执行删除。我不知道如何正确模拟 MatDialog,因此会发生删除:

it("should call 'delete' once when Submit button pressed and not cancelled", async(() => {
component.apis = [new Api({name: 'abc'})];
component.displayPermissions = [new Permission({name: 'abc'})];
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
compiled.querySelector('button').click();
expect(permissionService.delete.calls.count()).toBe(1, 'one call');
}));

我通过添加以下内容修复了它:

describe('MyComponent', () => {
let component: MyComponent;
let fixture: ComponentFixture<MyComponent>;

const dialogRefStub = {
afterClosed() {
return of(true);
}
};

const dialogStub = { open: () => dialogRefStub };

beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [],
declarations: [ MyComponent ],
providers: [
{ provide: MatDialog, useValue: dialogStub }
]
})
.compileComponents();
}));
//...
});

我尝试过的一些链接:

关于angular - dialogRef.afterClosed 不是一个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52968940/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com