Testing components with harnesses

Interact like a user, not like a unit of TypeScript

Component tests that dig into private fields become brittle the moment you refactor the template. Tests that interact through the rendered DOM — clicking, typing, asserting visible text — survive refactors and describe the contract a user actually experiences.

it('emits pay when the Pay button is clicked', () => {
  const fixture = TestBed.createComponent(InvoiceCardComponent);
  fixture.componentRef.setInput('invoice', { id: 7, title: 'Jun' });
  const spy = jasmine.createSpy('pay');
  fixture.componentInstance.pay.subscribe(spy);
  fixture.detectChanges();

  fixture.debugElement.query(By.css('button')).triggerEventHandler('click');
  expect(spy).toHaveBeenCalledWith(7);
});

Takeaways

  • Prefer DOM-level assertions — they encode the user-visible contract.
  • Use fakeAsync/tick to test time-based code deterministically.
  • Component harnesses (Angular CDK) raise the level of abstraction even further.

Enjoying This Lesson?

Your support helps create more comprehensive courses and lessons like this one. Help me build better learning experiences for everyone.

Support Awashyak