[Angular] Testing @Input and @Output bindings
2024-08-31 18:38:07
Component:
import { Component, Input, ChangeDetectionStrategy, EventEmitter, Output } from '@angular/core'; @Component({
selector: 'stock-counter',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div class="stock-counter">
<div>
<div
(keydown)="onKeyUp($event)"
(blur)="onBlur($event)"
(focus)="onFocus($event)"
tabindex="0">
<p>{{ value }}</p>
<div tabindex="-1">
<button type="button" tabindex="-1" (click)="increment()" [disabled]="value === max">
+
</button>
<button type="button" tabindex="-1" (click)="decrement()" [disabled]="value === min">
-
</button>
</div>
</div>
</div>
</div>
`
})
export class StockCounterComponent {
@Input() step: number = 1;
@Input() min: number = 0;
@Input() max: number = 100; @Output() changed = new EventEmitter<number>(); value: number = 0;
focused: boolean; increment() {
if (this.value < this.max) {
this.value = this.value + this.step;
this.changed.emit(this.value);
}
} decrement() {
if (this.value > this.min) {
this.value = this.value - this.step;
this.changed.emit(this.value);
}
} private onBlur(event: FocusEvent) {
this.focused = false;
event.preventDefault();
event.stopPropagation();
} private onKeyUp(event: KeyboardEvent) {
let handlers = {
ArrowDown: () => this.decrement(),
ArrowUp: () => this.increment()
}; if (handlers[event.code]) {
handlers[event.code]();
event.preventDefault();
event.stopPropagation();
}
} private onFocus(event: FocusEvent) {
this.focused = true;
event.preventDefault();
event.stopPropagation();
} }
Test @Input & @Output:
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {BrowserDynamicTestingModule, platformBrowserDynamicTesting} from '@angular/platform-browser-dynamic/testing'; import {StockCounterComponent} from './stock-counter.component'; TestBed.initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
); describe('StockCounterComponent', () => { let component: StockCounterComponent;
let fixture: ComponentFixture<StockCounterComponent>; beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
StockCounterComponent
]
}); fixture = TestBed.createComponent(StockCounterComponent);
component = fixture.componentInstance; component.value = ;
}); it('should not increase over the max value', () => {
component.step = ;
component.max = ;
component.increment();
component.increment();
expect(component.value).toEqual();
}); it('should not decrease below the min value', () => {
component.step = ;
component.min = ;
component.value = ;
component.decrement();
expect(component.value).toEqual();
component.decrement();
expect(component.value).toEqual();
}); it('should call the output on a value change', () => {
spyOn(component.changed, 'emit').and.callThrough();
component.step = ;
component.increment();
expect(component.changed.emit).toHaveBeenCalledWith()
});
});
最新文章
- EXCEL中多级分类汇总空白字段填充
- 无法加载协定为xx的终结点配置部分,因为找到了该协定的多个终结点配置。请按名称指示首选的终结点配置部分。
- 图像边缘检测——Sobel算子
- js 数组排序要注意的问题,返回的值最好为 -1, 0, 1之间的值
- Volatile总结
- struts2使用iterator标签显示嵌套Map - 云自无心水自闲 - BlogJava
- 解剖 Elasticsearch 集群 - 之三
- 在多个Activity中回传值(startActivityForResult())
- 【PHP】制作日历
- 第三方库API接口
- PostgreSQL:安装及中文显示
- SimMechanics/Second Generation倒立摆模型建立及初步仿真学习
- 复杂sql查询语句
- HTTP 500 Invalid bound statement错误
- Win10上使用VS2015编译Caffe2
- windows 创建共享文件夹
- python的执行过程
- Markdown编辑器使用说明
- Oracle创建database link(dblink)和同义词(synonym)
- error_log
热门文章
- Leetcode:signal_number_ii
- malloc,colloc,realloc内存分配,动态库,静态库的生成与调用
- samba-设定文件共享
- BZOJ3238: [Ahoi2013]差异(后缀数组)
- CORS原理
- 删除online日志測试及ora-600 [4194]错误的处理
- Android睡眠唤醒机制--Kernel态
- input表单验证(全面)
- Jpa 的Persistence.xml配置讲解
- [D3] Add image to the node