Testing Angular Components with Inputs and Outputs using Jest

io.component.ts import { Component, EventEmitter, Input, Output } from '@angular/core'; @Component({ selector: 'app-io', template: ` My favourite color is: {{color}} `, }) export class IoComponent { @Input() color = ''; @Output() colorChange = new EventEmitter(); changeColor() { this.colorChange.emit('pink'); } } When testing Angular components with @Input() and @Output(), we need to verify they work as they would in a real app. The best way? Mock their parent (host) component. This approach lets us: Control input values passed to the component. Capture emitted events exactly like a real parent would. io-component.spec.ts import { ComponentFixture, TestBed } from '@angular/core/testing'; import { IoComponent } from './io.component'; import { Component, ViewChild } from '@angular/core'; @Component({ template: ` ` }) class HostComponent { @ViewChild(IoComponent) ioComponent!: IoComponent; hostColor = 'red'; emittedColor = ''; onColorChanged(color: string) { this.emittedColor = color; }; } describe('IoComponent', () => { let hostComponent: HostComponent; let hostFixture: ComponentFixture; beforeEach(() => { TestBed.configureTestingModule({ declarations: [IoComponent, HostComponent] }); hostFixture = TestBed.createComponent(HostComponent); hostComponent = hostFixture.componentInstance; hostFixture.detectChanges(); }); it('should create', () => { expect(hostComponent.ioComponent).toBeTruthy(); }); describe('Input binding', () => { it('should receive initial color from host', () => { expect(hostComponent.ioComponent.color).toBe('red'); }); it('should update when host changes color', () => { hostComponent.hostColor = 'blue'; hostFixture.detectChanges(); expect(hostComponent.ioComponent.color).toBe('blue'); }); }); describe('Output binding', () => { it('should emit new color when button clicked', () => { const button = hostFixture.nativeElement.querySelector('button'); button.click(); expect(hostComponent.emittedColor).toBe('pink'); }); it('should emit through direct component call', () => { const spy = jest.spyOn(hostComponent.ioComponent.colorChange, 'emit'); hostComponent.ioComponent.changeColor(); expect(spy).toHaveBeenCalledWith('pink'); }); }); });

Apr 17, 2025 - 17:33
 0
Testing Angular Components with Inputs and Outputs using Jest

io.component.ts

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

@Component({
  selector: 'app-io',
  template: `
        
        

My favourite color is: {{color}} `, }) export class IoComponent { @Input() color = ''; @Output() colorChange = new EventEmitter<string>(); changeColor() { this.colorChange.emit('pink'); } }

When testing Angular components with @Input() and @Output(), we need to verify they work as they would in a real app. The best way? Mock their parent (host) component.

This approach lets us:

  • Control input values passed to the component.
  • Capture emitted events exactly like a real parent would.

io-component.spec.ts

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { IoComponent } from './io.component';
import { Component, ViewChild } from '@angular/core';

@Component({
  template: `
      
      `
})
class HostComponent {
  @ViewChild(IoComponent) ioComponent!: IoComponent;
  hostColor = 'red';
  emittedColor = '';
  onColorChanged(color: string) {
    this.emittedColor = color;
  };
}

describe('IoComponent', () => {
  let hostComponent: HostComponent;
  let hostFixture: ComponentFixture<HostComponent>;

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [IoComponent, HostComponent]
    });
    hostFixture = TestBed.createComponent(HostComponent);
    hostComponent = hostFixture.componentInstance;
    hostFixture.detectChanges();
  });

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

  describe('Input binding', () => {
    it('should receive initial color from host', () => {
      expect(hostComponent.ioComponent.color).toBe('red');
    });

    it('should update when host changes color', () => {
      hostComponent.hostColor = 'blue';
      hostFixture.detectChanges();
      expect(hostComponent.ioComponent.color).toBe('blue');
    });
  });

  describe('Output binding', () => {
    it('should emit new color when button clicked', () => {
      const button = hostFixture.nativeElement.querySelector('button');
      button.click();
      expect(hostComponent.emittedColor).toBe('pink');
    });

    it('should emit through direct component call', () => {
      const spy = jest.spyOn(hostComponent.ioComponent.colorChange, 'emit');
      hostComponent.ioComponent.changeColor();
      expect(spy).toHaveBeenCalledWith('pink');
    });
  });

});