이전 글에서 작성했던 테스트 코드는 mocking을 사용해서 구현했다. mocking을 사용하면 내가 테스트하고자 하는 계층에 물려있는 의존성들을 대신할 객체들을 손쉽게 만들어 낼 수 있다. 하지만 mocking을 남용하는 것은 코드 단계에서의 설계가 좋은 설계인지 나쁜 설계인지를 판별하기 어렵게 하는 단점이 있다.
먼저 이전 글에서 작성했던 구현 클래스를 보고 mocking 없이 테스트를 구현해 보면
// 이전 글에서 작성했던 구현 클래스
// blog.service.ts
import { Test1Repository } from './test2.repository';
import { Test2Repository } from './test2.repository2';
import { Test3Repository } from './test2.repository3';
import { Test4Repository } from './test2.repository4';
export class TestService {
constructor(
private _test1Repository: Test1Repository,
private _test2Repository: Test2Repository,
private _test3Repository: Test3Repository,
private _test4Repository: Test4Repository,
) {}
async 더하기(a: number, b: number): Promise<number> {
const 데이터베이스에있는숫자 = await this._test4Repository.findNumber();
if (!데이터베이스에있는숫자) {
return 0;
}
return a + b + 데이터베이스에있는숫자;
}
}
// 이전 글에서 작성한 mocking을 사용하지 않은 테스트코드
// mocking을 사용하지 않은 blog.test.ts
class MockTest1Repository {
// 기타 repository 코드들 1
}
class MockTest2Repository {
// 기타 repository 코드들 2
}
class MockTest3Repository {
// 기타 repository 코드들 3
}
class MockTest4Repository {
async updateShortfall(num: number): Promise<boolean> {
return true;
}
async findNumber() {
return 2;
}
}
describe('mocking 없이 가짜 객체를 이용한 테스트 코드 작성', () => {
it('더하기 함수 테스트코드', async () => {
const mockTest1Repository = new MockTest1Repository();
const mockTest2Repository = new MockTest2Repository();
const mockTest3Repository = new MockTest3Repository();
const mockTest4Repository = new MockTest4Repository();
const testService = new TestService(mockTest1Repository, mockTest2Repository, mockTest3Repository, mockTest4Repository);
const result = await testService.더하기(2, 3);
expect(result).toBe(7);
});
});
TestService 클래스에 있는 더하기라는 함수는 Test4Repository만을 의존해서 사용하고 있지만 더하기 함수를 테스트 하기 위해선 TestService 클래스가 의존하고 있는 모든 의존성들 (Test1Repository ~ Test2Repository)까지 주입해서 테스트를 진행해줘야 한다.
이렇게 Test4Repository 만들 의존하는 더하기라는 함수를 테스트하기 위해서 클래스가 의존하는 모든 의존성들을 가짜 객체로 만들어서 주입해 줘야 테스트가 가능하다. 하나의 테스트를 구현하기 위해 불필요한 의존성들의 주입도 해줘야 한다는 건 코드 디자인상의 문제가 있다는 의미이기 때문에 코드 디자인을 수정할 수 있게 해 준다.
// blogTest4.service.ts
import { Test4Repository } from './test2.repository4';
export class Test4Service {
constructor(private _test4Repository: Test4Repository) {}
async 더하기(a: number, b: number): Promise<number> {
const 데이터베이스에있는숫자 = await this._test4Repository.findNumber();
if (!데이터베이스에있는숫자) {
return 0;
}
return a + b + 데이터베이스에있는숫자;
}
}
// mocking을 사용하지 않은 blog.test.ts
class MockTest4Repository {
async updateShortfall(num: number): Promise<boolean> {
return true;
}
async findNumber() {
return 2;
}
}
describe('mocking 없이 가짜 객체를 이용한 테스트 코드 작성', () => {
it('더하기 함수 테스트코드', async () => {
const mockTest4Repository = new MockTest4Repository();
const testService = new Test4Service(mockTest4Repository);
const result = await testService.더하기(2, 3);
expect(result).toBe(7);
});
});
이처럼 mocking 없이 테스트를 구현하게 되면 코드 디자인상의 문제점을 알 수 있기 때문에 좀 더 구조적인 설계가 가능하다고 한다.
사실 테스트코드를 작성하는 게 아직은 많이 어색하기도 하고 mocking 없이 테스트 환경을 구축하는것도 어렵다. 하지만 아직 테스트 코드 작성에 익숙하지도 않고 구조적인 설계에 대해서도 부족하기 때문에 최대한 mocking없이 테스트 구현을 해봐야겠다.
'테스트 코드' 카테고리의 다른 글
테스트하기 쉬운 코드, 구조 (1) : mocking 사용한 테스트코드 작성 (0) | 2023.01.26 |
---|---|
테스트 코드 공부 기록_ 20221006 (1) | 2022.10.06 |