测试“ isChecked”道具是否已更改

时间:2019-01-02 18:40:59

标签: javascript angular typescript jasmine

我正在努力测试单击切换器后类的prop值是否正在改变。

所以这里有组件类(没什么复杂的-.-):

import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';

@Component({
selector: 'sps-flow-asset-switcher',
templateUrl: './flow-asset-switcher.component.html',
styleUrls: ['./flow-asset-switcher.component.scss'],
})

export class FlowAssetSwitcherComponent implements OnInit {

@Input() isChecked: boolean;
@Output() checkedChange = new EventEmitter<boolean>();

constructor() { }

ngOnInit() {}

onChange(e): void {
    this.isChecked = e.target.checked;
    this.checkedChange.emit(this.isChecked);
  }
}

这是模板:

<label class="switcher">
  <input
    type="checkbox"
    [checked]="isChecked"
    (change)="onChange($event)"
   />
  <span class="switcher__slider"></span>
</label>

在这里我开始测试:

import { async, ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';

import { FlowAssetSwitcherComponent } from './flow-asset-switcher.component';

fdescribe('FlowAssetSwitcherComponent', () => {
let component: FlowAssetSwitcherComponent;
let fixture: ComponentFixture<FlowAssetSwitcherComponent>;

beforeEach(async(() => {
    TestBed.configureTestingModule({
        imports: [FormsModule],
        declarations: [FlowAssetSwitcherComponent],
    })
        .compileComponents();
}));

beforeEach(() => {
    fixture = TestBed.createComponent(FlowAssetSwitcherComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
});

it('should create', () => {
    expect(component)
        .toBeTruthy();
});

it('should call onChange when switcher clicked', async(() => {
    spyOn(component, 'onChange');

    const button = fixture.debugElement.nativeElement.querySelector('.switcher__slider');
    button.click();

    fixture.whenStable()
        .then(() => {
            expect(component.onChange)
                .toHaveBeenCalled();
        });
}));

it('should change isChecked prop when switcher clicked', async(() => {
    const inputEl = fixture.debugElement.nativeElement.querySelector('input');
    component.isChecked = true;

    inputEl.dispatchEvent(new Event('change'));
    fixture.whenStable()
        .then(() => {
            expect(component.isChecked)
                .toEqual(false);
        });
}));
});

所以我正在测试3件事: 1.如果创建了组件-测试效果很好 2.切换器点击-测试正常 3.确保切换器的点击实际上会改变道具,该道具随后会发出-只有在将isChecked初始化为true值,false并应更改为true的情况下,测试才有效,测试失败并且不知道原因

所以我的基本问题是: 在执行某些操作(在这种情况下单击)后,如何检查道具价值是否已更改。

和其他问题: 我以前没有写过任何测试这些组件的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

您可以通过多种方式来执行此操作,但是我想保持简单,因此我建议以下内容:

  • 设置isChecked的值时,需要调用fixture.detectChanges(),以便将此值传播到输入元素。
  • 仅在没有任何实际更改的情况下触发更改事件才有效。我建议您只需单击输入元素即可调用您要查找的更改。
  • 这里没有异步的东西,因此async()并不是严格需要的。

为了展示这些变化,我整理了以下StackBlitz。以下是建议的规范,其中有上述更改:

it('should change isChecked from false to true when switcher clicked', () => {
    const inputEl = fixture.debugElement.nativeElement.querySelector('input');
    component.isChecked = false;
    fixture.detectChanges(); // invoke detectChanges right after you set 'isChecked'

    // inputEl.dispatchEvent(new Event('change')); // <-- This is not needed
    inputEl.click(); // Just invoke 'click' on the inputElement to simulate a mouse click event
    expect(component.isChecked)
        .toEqual(true);
});

顺便说一句-感谢您在问题中包含所有必需的详细信息!这样就可以轻松创建Stackblitz进行测试。

我希望这会有所帮助。