我在Angular Material菜单组件上关闭了一个自定义菜单,我想对其进行测试,但是它一直失败,并输出“ TypeError:无法读取未定义的属性'closeMenu'”
规格文件(在底部进行测试):
@Component({
selector: 'app-test',
template: `
<app-header-menu>
<button [matMenuTriggerFor]="test">Test</button>
<mat-menu #test="matMenu">menu content</mat-menu>
</app-header-menu>
`
})
class TestComponent {}
describe('HeaderMenuComponent', () => {
let component: TestComponent;
let fixture: ComponentFixture<TestComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ TestComponent, HeaderMenuComponent ],
imports: [
MatMenuModule
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it ('should close on click', () => {
document.dispatchEvent(new MouseEvent('click'));
expect(fixture.debugElement.query(By.css('app-header-menu')).nativeElement.trigger.closeMenu()).toHaveBeenCalled();
});
});
组件文件:
export class HeaderMenuComponent {
@ContentChild(MatMenuTrigger) trigger: MatMenuTrigger;
@HostListener('document:click', ['$event'])
onClick = event => {
if (this.trigger && this.trigger.menuOpen && !this.elRef.nativeElement.contains(event.target)) {
this.trigger.closeMenu();
}
}
}
有人知道我在做什么错吗?
答案 0 :(得分:1)
如果要测试@ContentChild(ren)
,使用包装器组件是正确的方法。
事实是,要测试触发器是否关闭,您需要先打开它,然后才能实际触发文档上的click事件。
PFB我的测试设置和测试本身。我还没有发现为什么单击按钮后mat-menu
没有打开。我直接使用内容子级触发了openMenu。
从某种意义上说,恕我直言,无需测试棱角材料的功能,因此无论如何,直接触发菜单对于您的测试用例来说应该没问题。
与测试设置不同,我使用了具有MatMenuTrigger的组件中的componentInstance
,因为本地的HtmlElement没有触发器或closeMenu方法来监视。
这里是stackblitz:
component.spec.ts
@Component({
selector: 'test-cmp',
template: `<app-component>
<button [matMenuTriggerFor]="test">Test</button>
<mat-menu #test="matMenu">menu content</mat-menu>
</app-component>`,
})
class TestWrapperComponent { }
describe('AppComponent', () => {
let component: AppComponent;
let fixture: ComponentFixture<TestWrapperComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [AppComponent, TestWrapperComponent],
providers: [],
imports: [MatMenuModule, BrowserAnimationsModule],
schemas: []
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(TestWrapperComponent);
component = fixture.debugElement.children[0].componentInstance;
});
it('should be created', () => {
fixture.detectChanges();
expect(component).toBeTruthy();
});
it ('should close on click', fakeAsync(() => {
fixture.detectChanges();
const closeMenueSpy: jasmine.Spy = spyOn(component.trigger, 'closeMenu');
// Not too sure why this menu doesn't open on click
// const debugElem: DebugElement = fixture.debugElement.query(By.css('button'));
// debugElem.triggerEventHandler('click', null);
component.trigger.openMenu();
tick();
expect(component.trigger.menuOpen).toBeTruthy();
document.dispatchEvent(new MouseEvent('click'));
tick();
expect(closeMenueSpy).toHaveBeenCalled();
}));
});