본문 바로가기

하루하루/개발

Mock 객체 활용법


얼마전에 기존에 꽃집총각이 만들어놓은 TDD 수정작업을 하였는데, Test하려는 객체가 많이 변한 탓에

정확한 Test를 진행하기가 힘들었다. 왜냐하면 새로운 기능들이 많이 추가되면서, 기존에 직접접근해도
 
괜찮았던 객체들이 지금은 직접접근하면 로직이 깨지는 경우가 많아져서, 대부분을 protected밑으로 넣어버렸다.

그러다보니 내부 변수들의 getter함수들도 같이 사라져버렸고, 외부에서는 오직 필요한 기능에 의한

함수 호출로 해당 객체를 사용하게 만들었다. 그래서 사용하기는 깔끔해졌다.

그런데 문제는 TDD를 수정하면서 발생했다.

Test는 객체의 내부 로직이 완벽하지 못할 때를 대비해서 하는 것인데, 대부분의 data에 직접 access

하는 함수들과 변수들은 protected밑에 있으니, 접근하지를 못했다.

그렇다고 Test때문에 protected를 풀수도 없는 일...ㅡㅡ;

몇 가지 getter함수를 만들어서 해결하던 중 우연히 작년 KGC에서 TDD와 스크럼에 대해 멋진 강의를 해주신

리니지2 서버 개발자인 박일님 블로그에서 재미있는 걸 발견했다.^^

class CTest
{
protected:
 int m_Test;
 void Test() {}
};

class CMockTest : public CTest
{
public:
 using CTest::m_Test; // 부모 클래스의 멤버를 public 으로 쓰겠다.
 using CTest::Test;
};

int _tmain(int argc, _TCHAR* argv[])
{
 CTest a;
 //a.m_Test = 1;  // protected 멤버 변수 접근할 수 없음.
 //a.Test();   // protected 멤버 함수 접근할 수 없음.

 CMockTest* pMockTest = (CMockTest*)(&a);
 pMockTest->m_Test = 1;  // CMockTest 로 강제 캐스팅하면 접근할 수 있음.
 pMockTest->Test();
 // a 가 CMockTest 객체가 아니어도 이렇게 쓸 수 있다는 점에 주의

 return 0;
}

결론 :
 테스트를 작성할 때는 기존 코드를 최대한 건드리지 않아야 한다.
 protected 따위는 보호받고 있다고 볼 수 없다. 차라리 안전한 테스트 코드를 작성해 두는 것이 더 좋다.
 강제 캐스팅 무섭다.

- 출처 : 박피디의 게임 아키텍트( http://parkpd.egloos.com/1746713 )


박일님 말씀처럼 Test때문에 기존의 코드를 건드리는 건 별로 좋은 생각이 아닌 것 같고, 그렇다고 기존의 코드를

최대한 건드리지 않을려고 하니, 제대로 된 Test를 하기 힘들고.....

그럴때 위의 방법이 정말 '킹왕짱~!'이다.

다시한번 TDD를 구성하면서 어려움을 겪고 있을 때 구원의 빛을 내려주신 박일님에게 감사하다는 말을 전하고 싶다.^^


'하루하루 > 개발' 카테고리의 다른 글

Multi-Logic-Threaded GameServer 3부  (0) 2010.05.17
Multi-Logic-Threaded GameServer 2부  (0) 2010.04.12
Multi-Logic-Threaded GameServer 1부  (0) 2010.04.09
LFH (Low Fragmentation Heap)  (0) 2009.04.12