角单元测试选择onChange spy on empty value(Angular unit test select onChange spy on empty value)

编程入门 行业动态 更新时间:2024-10-24 01:49:53
单元测试选择onChange spy on empty value(Angular unit test select onChange spy on empty value)

我想用间谍测试选择onChange事件,但我得到一个错误

Expected spy onSelect to have been called with [ 'en' ] but actual calls were [ '' ].

零件

@Component({ selector: 'tnos-languages', templateUrl: './languages.component.html', styleUrls: ['./languages.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) export class LanguagesComponent { @Input() languages: Language[]; @Output() change: EventEmitter<string> = new EventEmitter<string>(); constructor() { } onSelect(locale: string) { this.change.emit(locale); } }

模板

<select #selectLanguage (change)="onSelect(selectLanguage.value)"> <option *ngFor="let language of languages" [value]="language.locale"> {{language.label}} </option> </select>

测试

const languages: Language[] = [{ id: 1, label: 'Italiano', locale: 'it', default: false }, { id: 2, label: 'English', locale: 'en', default: true }]; fdescribe('LanguagesComponent', () => { let component: LanguagesComponent; let debugEl: DebugElement; let element: HTMLElement; let fixture: ComponentFixture<LanguagesComponent>; beforeEach(async(() => { TestBed.configureTestingModule({ imports: [BrowserModule, FormsModule], declarations: [LanguagesComponent] }) .compileComponents(); fixture = TestBed.overrideComponent(LanguagesComponent, { set: { selector: 'languages', templateUrl: './languages.component.html', changeDetection: ChangeDetectionStrategy.Default } }) .createComponent(LanguagesComponent); fixture.detectChanges(); })); beforeEach(() => { fixture = TestBed.createComponent(LanguagesComponent); component = fixture.componentInstance; debugEl = fixture.debugElement; element = debugEl.nativeElement; fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); it('should show `Italiano English` as option', async(() => { component.languages = languages; fixture.detectChanges(); fixture.whenStable().then(() => { const options = debugEl.queryAll(By.css('select option')); expect(options[0].nativeElement.text).toBe('Italiano'); expect(options[1].nativeElement.text).toBe('English'); }); })); it('should show `Italiano English` as option', async(() => { component.languages = languages; fixture.whenStable().then(() => { spyOn(component, 'onSelect'); const select = debugEl.query(By.css('select')).nativeElement; select.dispatchEvent(new Event('change')); fixture.detectChanges(); expect(component.onSelect).toHaveBeenCalled(); //expect(component.onSelect).toHaveBeenCalledWith('en'); }); })); it('should emit on change', fakeAsync(() => { component.languages = languages; fixture.whenStable().then(() => { spyOn(component.change, 'emit'); const select = debugEl.query(By.css('select')).nativeElement; select.dispatchEvent(new Event('change')); fixture.detectChanges(); expect(component.change.emit).toHaveBeenCalled(); expect(component.change.emit).toHaveBeenCalledWith('en'); }); })); });

解决

作为@Ayala的回复,但他/她只是忘了fixture.detectChanges();

it('should show `Italiano English` as option', async(() => { component.languages = languages; fixture.detectChanges(); fixture.whenStable().then(() => { spyOn(component, 'onSelect'); const select = debugEl.query(By.css('select')).nativeElement; select.value = select.options[1].value; select.dispatchEvent(new Event('change')); fixture.detectChanges(); expect(component.onSelect).toHaveBeenCalled(); expect(component.onSelect).toHaveBeenCalledWith('en'); }); }));

UPDATE

我认为这是摆脱异步和稳定的方式

it('should emit on change', () => { component.languages = languages; fixture.detectChanges(); spyOn(component.change, 'emit'); const select = debugEl.query(By.css('select')).nativeElement; select.value = select.options[1].value; select.dispatchEvent(new Event('change')); fixture.detectChanges(); expect(component.change.emit).toHaveBeenCalled(); expect(component.change.emit).toHaveBeenCalledWith('en'); });

I want to test a select onChange Event using spy on but I get an error

Expected spy onSelect to have been called with [ 'en' ] but actual calls were [ '' ].

component

@Component({ selector: 'tnos-languages', templateUrl: './languages.component.html', styleUrls: ['./languages.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush }) export class LanguagesComponent { @Input() languages: Language[]; @Output() change: EventEmitter<string> = new EventEmitter<string>(); constructor() { } onSelect(locale: string) { this.change.emit(locale); } }

template

<select #selectLanguage (change)="onSelect(selectLanguage.value)"> <option *ngFor="let language of languages" [value]="language.locale"> {{language.label}} </option> </select>

test

const languages: Language[] = [{ id: 1, label: 'Italiano', locale: 'it', default: false }, { id: 2, label: 'English', locale: 'en', default: true }]; fdescribe('LanguagesComponent', () => { let component: LanguagesComponent; let debugEl: DebugElement; let element: HTMLElement; let fixture: ComponentFixture<LanguagesComponent>; beforeEach(async(() => { TestBed.configureTestingModule({ imports: [BrowserModule, FormsModule], declarations: [LanguagesComponent] }) .compileComponents(); fixture = TestBed.overrideComponent(LanguagesComponent, { set: { selector: 'languages', templateUrl: './languages.component.html', changeDetection: ChangeDetectionStrategy.Default } }) .createComponent(LanguagesComponent); fixture.detectChanges(); })); beforeEach(() => { fixture = TestBed.createComponent(LanguagesComponent); component = fixture.componentInstance; debugEl = fixture.debugElement; element = debugEl.nativeElement; fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); it('should show `Italiano English` as option', async(() => { component.languages = languages; fixture.detectChanges(); fixture.whenStable().then(() => { const options = debugEl.queryAll(By.css('select option')); expect(options[0].nativeElement.text).toBe('Italiano'); expect(options[1].nativeElement.text).toBe('English'); }); })); it('should show `Italiano English` as option', async(() => { component.languages = languages; fixture.whenStable().then(() => { spyOn(component, 'onSelect'); const select = debugEl.query(By.css('select')).nativeElement; select.dispatchEvent(new Event('change')); fixture.detectChanges(); expect(component.onSelect).toHaveBeenCalled(); //expect(component.onSelect).toHaveBeenCalledWith('en'); }); })); it('should emit on change', fakeAsync(() => { component.languages = languages; fixture.whenStable().then(() => { spyOn(component.change, 'emit'); const select = debugEl.query(By.css('select')).nativeElement; select.dispatchEvent(new Event('change')); fixture.detectChanges(); expect(component.change.emit).toHaveBeenCalled(); expect(component.change.emit).toHaveBeenCalledWith('en'); }); })); });

RESOLVED

As the reply of @Ayala but he/she only forgot fixture.detectChanges();

it('should show `Italiano English` as option', async(() => { component.languages = languages; fixture.detectChanges(); fixture.whenStable().then(() => { spyOn(component, 'onSelect'); const select = debugEl.query(By.css('select')).nativeElement; select.value = select.options[1].value; select.dispatchEvent(new Event('change')); fixture.detectChanges(); expect(component.onSelect).toHaveBeenCalled(); expect(component.onSelect).toHaveBeenCalledWith('en'); }); }));

UPDATE

I think this is the way to go getting rid of async and stable

it('should emit on change', () => { component.languages = languages; fixture.detectChanges(); spyOn(component.change, 'emit'); const select = debugEl.query(By.css('select')).nativeElement; select.value = select.options[1].value; select.dispatchEvent(new Event('change')); fixture.detectChanges(); expect(component.change.emit).toHaveBeenCalled(); expect(component.change.emit).toHaveBeenCalledWith('en'); });

最满意答案

看起来您在分派'更改'事件之前没有更改选择值。

如果您尝试选择'en'选项,请尝试执行以下操作:

it('should show `Italiano English` as option', async(() => { component.languages = languages; fixture.whenStable().then(() => { spyOn(component, 'onSelect'); const select = debugEl.query(By.css('select')).nativeElement; select.value = select.options[1].value; // <-- select a new value select.dispatchEvent(new Event('change')); fixture.detectChanges(); expect(component.onSelect).toHaveBeenCalled(); expect(component.onSelect).toHaveBeenCalledWith('en'); }); }));

It looks like you are not changing the select value before you dispatch the 'change' event.

If you are trying to choose the 'en' option, try to do something like this:

it('should show `Italiano English` as option', async(() => { component.languages = languages; fixture.whenStable().then(() => { spyOn(component, 'onSelect'); const select = debugEl.query(By.css('select')).nativeElement; select.value = select.options[1].value; // <-- select a new value select.dispatchEvent(new Event('change')); fixture.detectChanges(); expect(component.onSelect).toHaveBeenCalled(); expect(component.onSelect).toHaveBeenCalledWith('en'); }); }));

更多推荐

本文发布于:2023-07-31 00:49:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1340466.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:单元测试   spy   onChange   empty   select

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!