如何在带有 jasmine 的 angular 组件中单击时触发 ngClass 更改
How do you trigger ngClass change on click in an angular component with jasmine
似乎没有触发点击,也没有将 ngClass 更改为在我尝试点击的按钮上处于活动状态。
--
HTML:
<div class='btn-group' role='group' aria-label="">
<button type='button'
id='btn-group-btn-{{i}}'
*ngFor="let button of buttons; index as i"
(click)="onClick($event, i)"
[ngClass]="{'active': button.isActive}"
class='btn btn-default btn-primary'>
{{button.displayTxt}}
</button>
</div>
组件:
export class AdmitOneBtnGroup {
@Input() public btnDisplayText: string;
@Input() public id: string;
@Output() public clickEvent = new EventEmitter();
@Input() public buttons: Array<ButtonGroupButton>; // Should be array of objects
public onClick($event, btnIndx) {
this.buttons.forEach((button, currentIndx) => {
button.isActive = (currentIndx === btnIndx);
});
this.clickEvent.emit(btnIndx);
}
};
export interface ButtonGroupButton {
isActive: boolean,
displayTxt: string,
}
测试:
let component: AdmitOneBtnGroup;
let fixture: ComponentFixture<AdmitOneBtnGroup>;
const testData: Array<ButtonGroupButton> = [
{
displayTxt: "abc",
isActive: true,
},
{
displayTxt: "def",
isActive: false,
},
{
displayTxt: "ghi",
isActive: false,
},
]
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [AdmitOneBtnGroup],
}).compileComponents()
}));
beforeEach(() => {
fixture = TestBed.createComponent(AdmitOneBtnGroup);
component = fixture.componentInstance;
component.buttons = testData;
component.id = 'button-group'
fixture.detectChanges();
});
it('#AdmitOneBtnGroupComponent button click should activate new button', async(() => {
spyOn(component, 'onClick');
const btn: HTMLElement = fixture.debugElement.nativeElement.querySelector('#btn-group-btn-1')
const clickEvent = new Event('click');
btn.dispatchEvent(clickEvent)
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(btn.getAttribute('class')).toContain("active");
})
}));
测试应该是单击第二个按钮并向其添加活动 class,但活动 class 保留在第一个按钮上..
我上面有一个事件说 expect(component.onClick).toHaveBeenCalled();结果是真的,所以我不确定点击是否没有被触发,或者它是否只是没有被更改的 ngClass。
您正在监视将按钮的 属性 的 isActive 设置为 true 的函数:
spyOn(component, 'onClick');
当您监视一个函数时,它不会被调用,除非您将 .and.callThrough() 添加到 spyOn 函数的末尾。如果你删除间谍,我希望它能工作。
或者,它可以是:
spyOn(component, 'onClick').and.callThrough();
...但我不确定您一开始为什么要监视该函数。
似乎没有触发点击,也没有将 ngClass 更改为在我尝试点击的按钮上处于活动状态。
--
HTML:
<div class='btn-group' role='group' aria-label="">
<button type='button'
id='btn-group-btn-{{i}}'
*ngFor="let button of buttons; index as i"
(click)="onClick($event, i)"
[ngClass]="{'active': button.isActive}"
class='btn btn-default btn-primary'>
{{button.displayTxt}}
</button>
</div>
组件:
export class AdmitOneBtnGroup {
@Input() public btnDisplayText: string;
@Input() public id: string;
@Output() public clickEvent = new EventEmitter();
@Input() public buttons: Array<ButtonGroupButton>; // Should be array of objects
public onClick($event, btnIndx) {
this.buttons.forEach((button, currentIndx) => {
button.isActive = (currentIndx === btnIndx);
});
this.clickEvent.emit(btnIndx);
}
};
export interface ButtonGroupButton {
isActive: boolean,
displayTxt: string,
}
测试:
let component: AdmitOneBtnGroup;
let fixture: ComponentFixture<AdmitOneBtnGroup>;
const testData: Array<ButtonGroupButton> = [
{
displayTxt: "abc",
isActive: true,
},
{
displayTxt: "def",
isActive: false,
},
{
displayTxt: "ghi",
isActive: false,
},
]
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [AdmitOneBtnGroup],
}).compileComponents()
}));
beforeEach(() => {
fixture = TestBed.createComponent(AdmitOneBtnGroup);
component = fixture.componentInstance;
component.buttons = testData;
component.id = 'button-group'
fixture.detectChanges();
});
it('#AdmitOneBtnGroupComponent button click should activate new button', async(() => {
spyOn(component, 'onClick');
const btn: HTMLElement = fixture.debugElement.nativeElement.querySelector('#btn-group-btn-1')
const clickEvent = new Event('click');
btn.dispatchEvent(clickEvent)
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(btn.getAttribute('class')).toContain("active");
})
}));
测试应该是单击第二个按钮并向其添加活动 class,但活动 class 保留在第一个按钮上..
我上面有一个事件说 expect(component.onClick).toHaveBeenCalled();结果是真的,所以我不确定点击是否没有被触发,或者它是否只是没有被更改的 ngClass。
您正在监视将按钮的 属性 的 isActive 设置为 true 的函数:
spyOn(component, 'onClick');
当您监视一个函数时,它不会被调用,除非您将 .and.callThrough() 添加到 spyOn 函数的末尾。如果你删除间谍,我希望它能工作。
或者,它可以是:
spyOn(component, 'onClick').and.callThrough();
...但我不确定您一开始为什么要监视该函数。