Min*_*inz 6 unit-testing jasmine angular
嗨,我正在做单元测试并试图获得我的订阅的覆盖范围。但是它一直失败并出现错误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();
}
});
}
Run Code Online (Sandbox Code Playgroud)
这是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);
}
);
}
}
Run Code Online (Sandbox Code Playgroud)
我将 Sam Tsai 的回答更进一步,并创建了一个存根文件以更简洁。这是存根文件的内容:
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) };
}
}
Run Code Online (Sandbox Code Playgroud)
然后在 .spec.ts 文件中使用这样的存根:
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();
}));
//...
});
Run Code Online (Sandbox Code Playgroud)
而在实际测试中,您可以通过调用 setResult() 函数将返回值设置为 true 或 false 来分别模拟单击“确定”或“取消”按钮:
dialogStub.setResult(true);
Run Code Online (Sandbox Code Playgroud)
或者
dialogStub.setResult(false);
Run Code Online (Sandbox Code Playgroud)
注意:存根测试的默认值“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');
}));
Run Code Online (Sandbox Code Playgroud)
原答案
我到处寻找一种简洁的方法来模拟 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');
}));
Run Code Online (Sandbox Code Playgroud)
我通过添加以下内容来修复它:
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();
}));
//...
});
Run Code Online (Sandbox Code Playgroud)
我试过的一些链接:
| 归档时间: |
|
| 查看次数: |
7146 次 |
| 最近记录: |