한동안 개발 잉여력이 떨어져서 오래 쉬었네요.
회사에서 바쁘면 집에서 개발을 덜하게 됩니다.
개발을 천천히 하니 글 쓸 일을 더욱 없다는게...
그렇다해서 지금 바쁘지 않다는건 아니지만.
더 밀리면 안쓰고 넘어갈 것 같아서 기록합니다.
기록하다보면 더 정리되는 기분도 있구요.
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