Angular Test Tips (Mock)

2019. 6. 1. 15:35

한동안 개발 잉여력이 떨어져서 오래 쉬었네요.

회사에서 바쁘면 집에서 개발을 덜하게 됩니다.

개발을 천천히 하니 글 쓸 일을 더욱 없다는게...

 

그렇다해서 지금 바쁘지 않다는건 아니지만.

더 밀리면 안쓰고 넘어갈 것 같아서 기록합니다.

기록하다보면 더 정리되는 기분도 있구요.

 

TDD를 연습하자는 취지로 진행중인데,

소스가 많아질 수록 점점 Test가 어려워집니다.

Angular 또한 예외는 아니구요.

 

그 어려움을 덜어낸 방법 2가지 공유합니다.

 

1. Component Mocking

 

자식(Child) 컴포넌트를 포함하는

부모(Parent) 컴포넌트를 테스트하다보면

점점 테스트 설정이 무거워집니다.

 

부모 컴포넌트의 의존성 뿐 아니라

자식 컴포넌트의 의존성을 모두 주입해야하니까요.

그래서 자식컴포넌트를 Mock으로 주입하고

자식의 의존성은 생략해버리는 것이 유용합니다.

 

제 프로젝트는 아래와 같은 포함관계가 있습니다.

Budget > Calendar > Day Component

Budget 컴포넌트의 테스트가 비대해지는 중이죠.

그래서 Calendar 컴포넌트를 Mock을 했습니다.

의존성도 덜어냈구요.

그 방법은 아래와 같습니다.

 

1) Mock 컴포넌트의 선언

 

테스트(spec.js)에 가짜(Mock) 컴포넌트를 선언합니다. 실제와 동일한 selector를 가지도록 말이지요. Input, Output과 같이 테스트가 필요한 부분은 포함합니다.

...
@Component({
  selector: 'app-calendar',
  template: 'mock calendar'
})
class MockCalendarComponent {
  @Input('date') date: Date;
  @Output('dateChange') dateChange: EventEmitter = new EventEmitter();
}

 

2) Mock 컴포넌트의 사용

 

하위 컴포넌트를 추가해주었던 declarations에 선언해준 Mock 컴포넌트를 넣습니다.

describe('BudgetComponent', () => {
  let component: BudgetComponent;
  let fixture: ComponentFixture;
  let testableDailyExpenseState: Observable;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [BudgetComponent, MockCalendarComponent],
      imports: [
      ...
      ])]
    }).compileComponents();
  }));
  ...

 

이제 Calendar나 Day 컴포넌트의 의존성은 Budget 컴포넌트의 테스트에 더이상 필요가 없습니다.

자식 컴포넌트를 위한 설정 코드들도 덜어집니다.

 

2. Override Private Property

 

사실 이 방법은 좋은 방법은 아닙니다.

부득이하게 쓸 경우가 있어서 정리해둡니다.

NGXS를 쓰다보니 테스트가 난해하더군요.

Store 값을 변경하기가 까다로워서요. 

 

Selector로 가져오는 값이 private이기 때문.

Javascript의 Object.defineProperty를 이용했습니다. 이미 component에 정의된 속성을 수정하고 테스트용 값을 넣어주는 방식입니다.

beforeEach(() => {
    ...
    Object.defineProperty(component, 'dailyExpense$', { writable: true });
    let dailyExpenseState = {
      //test data
      ...
    }
    testableDailyExpenseState = of(dailyExpenseState)
    component.dailyExpense$ = testableDailyExpenseState;
    ...
  });

위와 같이 component의 private 속성에

원하는 테스트 값을 넣는 것이 가능합니다.

 

위와 같은 방법을 이용하여 Angular의 테스트를 조금 더 수월하게 하였습니다.

 

Angular 테스트 코드가 점점 무거워지고,

수많은 의존성과 설정에 불편하신 분들께

도움이 되었으면 좋겠습니다.

 

전체 소스는 아래 github에서 보실 수 있습니다.

소스주소: https://github.com/jsrho1023/account-book

'IT Tech > Angular' 카테고리의 다른 글

Angular Test Tips (Mock)  (0) 2019.06.01
Angular Dialog(Material Design)  (0) 2019.01.01
Angular Component Communication (Output)  (0) 2018.12.16
Angular Component Communication (Input)  (0) 2018.12.02
Angular Test Headless  (0) 2018.11.18
Angular Pipes  (0) 2018.11.12

TechTrip IT Tech/Angular , , , , ,