1

So I am trying to add two test to insure that two binding is actually setup for a property. Not sure what I am missing here, but feels like I am pretty close.

Here is the html:

   <input [(ngModel)]="value" (change)="onChange()"/>

Here is the component class:

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

@Component({
  selector: 'cs-string-field',
  templateUrl: './string-field.component.html',
  styleUrls: ['./string-field.component.scss']
})
export class StringFieldComponent implements OnInit {
  @Input() value: string;

  @Output() change = new EventEmitter<string>();
  constructor() { }

  ngOnInit(): void {
  }

  onChange = () => this.change.emit(this.value);
}

Last but not least here is my tests. The last one is failing:

import { ComponentFixture, TestBed } from '@angular/core/testing';

import { StringFieldComponent } from './string-field.component';
import { FormsModule } from '@angular/forms';

describe('StringFieldComponent', () => {
  let component: StringFieldComponent;
  let fixture: ComponentFixture<StringFieldComponent>;

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

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

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

  it('should have an input tag with type text', () => {

    const sut = fixture.nativeElement
      .querySelector('input[type="text"]');

    expect(sut).toBeTruthy();
  });

  it('should emit a value on change', done => {
    const value = "Pretty Kitty";
    const event = new Event('change');
    component.value = value;
    fixture.detectChanges();
    const ele = fixture.nativeElement
      .querySelector('input[type="text"]');

    component.change.subscribe(res => {
      expect(res).toBe(value);
      done();
    })

    ele.dispatchEvent(event);
  });

  it('should update value on input', done => {
    const value = "Pretty Kitty";
    const event = new Event('change');
    component.value = '';
    fixture.detectChanges();
    const ele = fixture.nativeElement
      .querySelector('input[type="text"]');

    component.change.subscribe(res => {
      expect(res).toBe(value);
      done();
    })

    ele.value = value;
    ele.dispatchEvent(event);
  });
});

I feel like I am missing something really simple here, but the value is not getting set on the component.

1 Answer 1

1

So it took me way longer then I want to admit to see this, but the last test was missing one thing. The input event has to be fired for the two binding to work. So here is the correct test and I now have my sanity back.

  it('should update value on input', done => {
    const value = "Pretty Kitty";
    const inputEvent = new Event('input');
    const event = new Event('change');
    component.value = '';
    fixture.detectChanges();
    const ele = fixture.nativeElement
      .querySelector('input[type="text"]');

    component.change.subscribe(res => {
      expect(res).toBe(value);
      done();
    })

    ele.value = value;
    ele.dispatchEvent(inputEvent);
    ele.dispatchEvent(event);
  });
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.