Angular Unit Testing ด้วย Jasmine และ TestBed

#angular12 เม.ย. 2569

ทำไมต้อง Test Angular

การเขียน unit test ช่วยให้มั่นใจว่าโค้ดทำงานถูกต้อง และป้องกัน regression เมื่อแก้ไขโค้ด

ทดสอบ Component

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { CounterComponent } from './counter.component';

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

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [CounterComponent]
    }).compileComponents();

    fixture = TestBed.createComponent(CounterComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

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

  it('should increment count', () => {
    component.increment();
    expect(component.count()).toBe(1);
  });

  it('should show count in template', () => {
    component.count.set(5);
    fixture.detectChanges();
    const el = fixture.nativeElement.querySelector('p');
    expect(el.textContent).toContain('5');
  });
});

ทดสอบ Service

import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { UserService } from './user.service';

describe('UserService', () => {
  let service: UserService;
  let httpMock: HttpTestingController;

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

  afterEach(() => httpMock.verify());

  it('should get users', () => {
    const mockUsers = [{ id: 1, name: 'สมชาย' }];

    service.getUsers().subscribe(users => {
      expect(users).toEqual(mockUsers);
    });

    const req = httpMock.expectOne('/api/users');
    expect(req.request.method).toBe('GET');
    req.flush(mockUsers);
  });
});

Mock Service

const mockUserService = {
  getUsers: jasmine.createSpy('getUsers').and.returnValue(of([]))
};

TestBed.configureTestingModule({
  providers: [
    { provide: UserService, useValue: mockUserService }
  ]
});

รัน Test

ng test              # watch mode
ng test --no-watch   # รันครั้งเดียว
ng test --code-coverage  # ดู coverage

สรุป

การเขียน test ใน Angular ไม่ยากอย่างที่คิด TestBed ช่วยให้ setup environment ได้ง่าย ควรเขียน test ควบคู่กับการพัฒนาตั้งแต่ต้นครับ