0Pricing
Angular Academy · 강의

서비스와 의존성 모의 처리

DI를 통해 테스트 대역을 제공합니다.

서비스와 의존성 모의 처리은(는) CoddyKit의 무료 Angular Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Angular Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Angular Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

의존성을 모의 객체로 만드는 이유

컴포넌트 테스트는 컴포넌트를 격리해야 합니다. HttpClient 기반 서비스를 주입받는다면 실제 네트워크 호출을 실행하고 싶지 않을 것입니다. 대신 test double, 즉 제어된 데이터를 반환하는 가짜 객체를 제공하여 테스트를 빠르고 결정적으로 만듭니다.

useValue로 가짜 객체 제공하기

가장 간단한 대체물은 useValue로 제공하는 일반 객체입니다. 컴포넌트가 요청하는 것과 동일한 주입 토큰으로 제공합니다.

const fakeApi = { getUser: () => of({ name: 'Ada' }) };
TestBed.configureTestingModule({
  imports: [ProfileComponent],
  providers: [{ provide: UserApi, useValue: fakeApi }],
});

Jasmine 스파이

jasmine.createSpyObj는 스파이 메서드를 포함한 가짜 객체를 만듭니다. 따라서 반환값을 대체하고 호출 여부도 검증할 수 있습니다.

const apiSpy = jasmine.createSpyObj<UserApi>('UserApi', ['getUser']);
apiSpy.getUser.and.returnValue(of({ name: 'Ada' }));
TestBed.configureTestingModule({
  providers: [{ provide: UserApi, useValue: apiSpy }],
});

서비스가 호출되었는지 검증하기

컴포넌트에서 동작을 수행한 후 스파이가 예상한 인수를 받았는지 확인합니다.

fixture.componentInstance.load(7);
fixture.detectChanges();
expect(apiSpy.getUser).toHaveBeenCalledWith(7);
expect(apiSpy.getUser).toHaveBeenCalledTimes(1);

모의 객체에서 Observable 반환하기

서비스는 Observable을 반환하는 경우가 많습니다. 동기적인 성공에는 RxJS of()를, 실패에는 throwError()를 사용하여 두 분기를 모두 테스트할 수 있습니다.

import { of, throwError } from 'rxjs';

apiSpy.getUser.and.returnValue(of({ name: 'Ada' }));     // success
apiSpy.getUser.and.returnValue(throwError(() => new Error('boom'))); // error

재사용 가능한 가짜 객체에 useClass 사용하기

하나의 가짜 객체를 여러 사양에서 재사용한다면 class를 정의하고 useClass로 연결합니다.

class FakeUserApi {
  getUser() { return of({ name: 'Test' }); }
}
TestBed.configureTestingModule({
  providers: [{ provide: UserApi, useClass: FakeUserApi }],
});

HttpTestingController로 HttpClient 모의 처리하기

전체 서비스를 가짜로 대체하지 않고 HTTP를 호출하는 서비스를 테스트하려면 provideHttpClientTesting()을 가져오고 HttpTestingController를 통해 요청을 처리합니다.

import { provideHttpClient } from '@angular/common/http';
import { provideHttpClientTesting, HttpTestingController } from '@angular/common/http/testing';

TestBed.configureTestingModule({
  providers: [provideHttpClient(), provideHttpClientTesting()],
});

HTTP 요청 처리하기

요청을 예상하고, 가짜 데이터로 응답한 다음, 예상하지 못한 호출이 남아 있지 않은지 확인합니다.

const http = TestBed.inject(HttpTestingController);
service.load();
const req = http.expectOne('/api/users/7');
expect(req.request.method).toBe('GET');
req.flush({ name: 'Ada' });
http.verify();

각 명세에서 프로바이더 재정의하기

때로는 하나의 테스트에서 다른 가짜 객체가 필요합니다. createComponent 전에 TestBed.overrideProvider()를 사용합니다.

TestBed.overrideProvider(UserApi, {
  useValue: { getUser: () => throwError(() => new Error('fail')) },
});
const fixture = TestBed.createComponent(ProfileComponent);

필요한 만큼만 모의 객체 만들기

좋은 테스트 대역은 컴포넌트가 실제로 사용하는 메서드만 구현합니다. 모의 객체를 지나치게 많이 만들면 테스트가 내부 구현에 결합되고, 너무 적게 만들면 실제 부작용이 새어 나옵니다. 컴포넌트가 의존하는 공개 계약에 맞추어야 합니다.

실제 서비스 메서드 감시하기

실제 서비스를 유지하면서 spyOn(instance, 'method')를 사용해 특정 메서드 하나를 감시할 수도 있습니다. 서비스 대부분은 무해하지만 특정 호출 하나를 가로채야 할 때 유용합니다.

const svc = TestBed.inject(AnalyticsService);
spyOn(svc, 'track');
fixture.componentInstance.onClick();
expect(svc.track).toHaveBeenCalledWith('click');

빠른 확인

가짜 객체가 호출을 확인하면서 반환 값도 제어하도록 하려면 어떻게 해야 할까요?

복습

useValue, useClass, Jasmine 스파이를 사용해 실제 의존성을 테스트 대역으로 대체했고, of/throwError로 Observable을 반환했으며, HttpTestingController를 통해 HTTP를 테스트하고 명세별로 프로바이더를 재정의했습니다. 컴포넌트가 사용하는 계약만 모의 처리해야 합니다.

자주 묻는 질문

“서비스와 의존성 모의 처리” 강의는 무료인가요?

네 — “서비스와 의존성 모의 처리” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Angular Academy 강의 전체를 잠금 해제할 수 있습니다. Angular Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“서비스와 의존성 모의 처리”에서 뭘 배우나요?

DI를 통해 테스트 대역을 제공합니다. 브라우저에서 직접 실행하는 실습 코드로 Angular Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Angular Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Angular Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.

“서비스와 의존성 모의 처리” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Angular Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Angular Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. TestBed와 컴포넌트 픽스처
  2. 입력, 출력, DOM 테스트
  3. 서비스와 의존성 모의 처리
  4. Signals와 비동기 코드 테스트
← Angular Academy(으)로 돌아가기