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/tickto 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