DEV Community

Cover image for Angular + Jest: All the Unit Test Cases You'll Ever Need (With Live Examples)
Rajat
Rajat

Posted on

Angular + Jest: All the Unit Test Cases You'll Ever Need (With Live Examples)

Are You Really Testing Your Angular App the Right Way?

Unit testing isn't just about “getting 100% code coverage.” It’s about writing meaningful tests that simulate real-world use cases—and Jest, paired with Angular, is a powerful combo to do exactly that.

In this guide, we're not just going to tell you what to test. We’ll show you how to test every critical scenario in Angular using Jest—with hands-on demo code, best practices, and a professional yet easygoing tone to keep you engaged.


What You'll Learn

By the end of this article, you'll be able to:

  • Write professional Angular unit tests using Jest
  • Test every real-world case from API calls to DOM interactions
  • Mock services, HTTP calls, timers, observables, forms, pipes, directives and more
  • Use fakeAsync, tick(), and spies like a pro
  • Structure your tests for readability, maintainability, and performance

🔧 1. API Calls: Testing HTTPClient with Jest

👉 What to test:

  • Successful API response
  • Error response
  • Params & headers

📦 Example:

// my-service.spec.ts
import { TestBed } from '@angular/core/testing';
import { MyService } from './my-service';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';

describe('MyService', () => {
  let service: MyService;
  let http: HttpTestingController;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      providers: [MyService],
    });
    service = TestBed.inject(MyService);
    http = TestBed.inject(HttpTestingController);
  });

  it('should fetch data from API', () => {
    const mockResponse = { name: 'Angular' };

    service.getData().subscribe((res) => {
      expect(res).toEqual(mockResponse);
    });

    const req = http.expectOne('/api/data');
    expect(req.request.method).toBe('GET');
    req.flush(mockResponse);
  });

  it('should handle error', () => {
    service.getData().subscribe({
      error: (err) => {
        expect(err.status).toBe(500);
      },
    });

    const req = http.expectOne('/api/data');
    req.flush('Error', { status: 500, statusText: 'Server Error' });
  });
});

Enter fullscreen mode Exit fullscreen mode

⏱️ 2. setTimeout, setInterval, and Delayed Execution

Jest’s fake timers make this smooth.

📦 Example:

import { fakeAsync, tick } from '@angular/core/testing';

it('should delay execution using setTimeout', fakeAsync(() => {
  let called = false;

  setTimeout(() => {
    called = true;
  }, 1000);

  tick(1000);
  expect(called).toBeTrue();
}));

Enter fullscreen mode Exit fullscreen mode

💡 3. Component Input/Output and DOM Testing

Let’s say we have a component that emits a value on a button click:

<!-- child.component.html -->
<button (click)="emitValue()">Click me</button>

Enter fullscreen mode Exit fullscreen mode
// child.component.ts
@Output() valueEmitted = new EventEmitter<string>();

emitValue() {
  this.valueEmitted.emit('test');
}

Enter fullscreen mode Exit fullscreen mode

📦 Test it like this:

it('should emit value on button click', () => {
  const fixture = TestBed.createComponent(ChildComponent);
  const component = fixture.componentInstance;

  jest.spyOn(component.valueEmitted, 'emit');
  const button = fixture.nativeElement.querySelector('button');

  button.click();

  expect(component.valueEmitted.emit).toHaveBeenCalledWith('test');
});

Enter fullscreen mode Exit fullscreen mode

🧪 4. Reactive Forms: Validators, State, & Values

📦 Example:

it('should validate form fields', () => {
  const form = new FormGroup({
    email: new FormControl('', [Validators.required, Validators.email]),
  });

  form.setValue({ email: '' });
  expect(form.valid).toBeFalse();

  form.setValue({ email: 'user@example.com' });
  expect(form.valid).toBeTrue();
});

Enter fullscreen mode Exit fullscreen mode

🔁 5. Pipes & Directives

Pipe Test:

it('should transform the text to uppercase', () => {
  const pipe = new UpperCasePipe();
  expect(pipe.transform('angular')).toBe('ANGULAR');
});

Enter fullscreen mode Exit fullscreen mode

🔄 6. Service with BehaviorSubject

📦 Example:

it('should emit new value from BehaviorSubject', () => {
  const service = new MyService();
  const result: string[] = [];

  service.observable$.subscribe((val) => result.push(val));
  service.updateValue('hello');

  expect(result).toContain('hello');
});

Enter fullscreen mode Exit fullscreen mode

🔀 7. Testing Custom Directive

Imagine a directive that highlights text on hover:

it('should add class on mouseenter', () => {
  const directive = new HighlightDirective(elRefMock, rendererMock);
  directive.onMouseEnter();

  expect(rendererMock.addClass).toHaveBeenCalledWith(elRefMock.nativeElement, 'highlight');
});

Enter fullscreen mode Exit fullscreen mode

🎯 Bonus Tips

  • Use jest.spyOn() instead of Jasmine spies
  • jest.fn() for mocking callbacks and dependencies
  • Always clean up side effects (afterEach)

🗒️ Final Thoughts

Testing is more than checking boxes. When done right, it prevents bugs, documents intent, and gives you confidence in refactoring.

If you’ve made it this far, you’re already ahead of many developers who avoid unit testing out of fear or frustration.



🎯 Your Turn, Devs!

👀 Did this article spark new ideas or help solve a real problem?

💬 I'd love to hear about it!

✅ Are you already using this technique in your Angular or frontend project?

🧠 Got questions, doubts, or your own twist on the approach?

Drop them in the comments below — let’s learn together!


🙌 Let’s Grow Together!

If this article added value to your dev journey:

🔁 Share it with your team, tech friends, or community — you never know who might need it right now.

📌 Save it for later and revisit as a quick reference.


🚀 Follow Me for More Angular & Frontend Goodness:

I regularly share hands-on tutorials, clean code tips, scalable frontend architecture, and real-world problem-solving guides.

  • 💼 LinkedIn — Let’s connect professionally
  • 🎥 Threads — Short-form frontend insights
  • 🐦 X (Twitter) — Developer banter + code snippets
  • 👥 BlueSky — Stay up to date on frontend trends
  • 🌟 GitHub Projects — Explore code in action
  • 🌐 Website — Everything in one place
  • 📚 Medium Blog — Long-form content and deep-dives
  • 💬 Dev Blog — Free Long-form content and deep-dives
  • ✉️ Substack — Weekly frontend stories & curated resources
  • 🧩 Portfolio — Projects, talks, and recognitions

🎉 If you found this article valuable:

  • Leave a 👏 Clap
  • Drop a 💬 Comment
  • Hit 🔔 Follow for more weekly frontend insights

Let’s build cleaner, faster, and smarter web apps — together.

Stay tuned for more Angular tips, patterns, and performance tricks! 🧪🧠🚀

Top comments (0)