【问题标题】:Testing if 'isChecked' prop has changed测试 'isChecked' 属性是否已更改
【发布时间】:2019-05-29 09:47:01
【问题描述】:

我正在努力测试类的道具值是否在单击切换器后发生变化。

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

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 初始化为真值时才有效,如果它是假的并且应该更改为真测试失败并且不知道原因

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

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

【问题讨论】:

    标签: javascript angular typescript jasmine


    【解决方案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 进行测试变得容易。

    我希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-14
      • 1970-01-01
      • 1970-01-01
      • 2017-11-10
      • 2012-03-07
      • 2019-01-12
      • 1970-01-01
      • 2019-08-18
      相关资源
      最近更新 更多