Я взял ответ Сэма Цая на шаг вперед и создал более короткий файл-заглушку.Вот содержимое файла заглушки:
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 вы используете заглушку следующим образом:
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();
}));
//...
});
И в реальном тесте вы можете установить возвращаемое значениев true или false для имитации нажатия кнопки «ОК» или «Отмена» соответственно путем вызова функции setResult ():
dialogStub.setResult(true);
или
dialogStub.setResult(false);
Примечание: значение по умолчанию длязаглушка проверяет «ОК», поэтому вам не нужно вызывать функцию, если вы просто проверяете «ОК».
Приведенные ниже тесты сначала имитируют «Отмена», а затем нажатие кнопки «ОК»:
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 не является функцией .(см. некоторые ссылки, которые я пробовал внизу).Ничто из того, что я нашел, не было правильным решением, пока я не попробовал ответ Сэма Цая на этот вопрос.Это было простое решение, которое избавило меня от всех моих ошибок и позволило мне правильно протестировать свое приложение.Хотел бы я найти это, прежде чем тратить столько времени на все остальные ссылки.
Это модульный тест, который не прошел;это событие не удалось выполнить ('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();
}));
//...
});
Некоторые ссылки, которые я пробовал: