EasyMock(old)을 활용한 협업 테스트 에서 소개한 불편한 EasyMock 1.2. Mock 객체를 사용한 테스트 자체도 이해하는데 장벽이지만, EasyMock 1.2는 벽을 이중으로 만든다. 기억하기도 어려울 뿐더러 직관성도 떨어진다. 우선 EasyMock과 ClassExtension의 차이가 나타나지 않도록 createControl 팩토리 메소드를 래핑하는 선에서 그냥 썼다. 어제 밤 팀원에서 Mock을 이용한 테스트에 대해 안내하면서 API가 어려워 리듬을 잃어버리는 일이 발생했다.
취침에 들어가려고 발을 씻던 중에 아이디어를 실험하기 위해 컴퓨터 앞에 앉았다. 내일을 위해 오버하면 안되는데... 일단 EasyMock 문서가 부족하다고 불평했었는데, 1.2 안에 sample이 있었다. 이런... 샘플을 무시하는 습관이라니..ㅡㅡ;
API 대치/래핑을 통해 샘플의 코드를 개선할 수 있다면 1차적으로는 성공이다. 그리고, 그것이 최소한 EasyMock 1.2를 써본 팀원에게 좋은 평을 받는다면 졸린 눈으로 버틴 시간이 보상받을 것이다.
예제의 setUp에서 나온 코드. 전형적인 쌍이다. 사실 난 MockControl이란 것이 마음에 들지 않는다. MockControl은 두 가지 역할을 갖는다. 하나는 Mock객체에 대한 기대값을 설정하는 것이고, 다른 하나는 테스트 수행을 위한 컨트롤 역할이다. 어찌 되었든 MockControl 보다는 MockExpections이 나은 듯 하다. 위키피디아에서 본 Setting expectations 문구가 힘을 실리게 해준다. 위의 두 줄의 문장을 하나로 바꾸고 싶은데, 리턴이 두 개인지라 어려워보인다.
사실상 저 둘은 불가분의 관계로 보이니까 Spring의 ModelAndView 처럼 하나로 묶어보자.
MockExpections 라는 클래스로 합치는 것을 시도해보았으나 결국은 Mock 객체 호출이 필요했다. 여기까지는 별반 차이가 없어 보인다. 하지만, 실행 코드는 좀 간결하고 직관적으로 바뀌었다. 아래와 같은 코드였는데
취침에 들어가려고 발을 씻던 중에 아이디어를 실험하기 위해 컴퓨터 앞에 앉았다. 내일을 위해 오버하면 안되는데... 일단 EasyMock 문서가 부족하다고 불평했었는데, 1.2 안에 sample이 있었다. 이런... 샘플을 무시하는 습관이라니..ㅡㅡ;
API 대치/래핑을 통해 샘플의 코드를 개선할 수 있다면 1차적으로는 성공이다. 그리고, 그것이 최소한 EasyMock 1.2를 써본 팀원에게 좋은 평을 받는다면 졸린 눈으로 버틴 시간이 보상받을 것이다.
control = MockControl.createControl(IMethods.class);
mock = (IMethods) control.getMock();
mock = (IMethods) control.getMock();
예제의 setUp에서 나온 코드. 전형적인 쌍이다. 사실 난 MockControl이란 것이 마음에 들지 않는다. MockControl은 두 가지 역할을 갖는다. 하나는 Mock객체에 대한 기대값을 설정하는 것이고, 다른 하나는 테스트 수행을 위한 컨트롤 역할이다. 어찌 되었든 MockControl 보다는 MockExpections이 나은 듯 하다. 위키피디아에서 본 Setting expectations 문구가 힘을 실리게 해준다. 위의 두 줄의 문장을 하나로 바꾸고 싶은데, 리턴이 두 개인지라 어려워보인다.
사실상 저 둘은 불가분의 관계로 보이니까 Spring의 ModelAndView 처럼 하나로 묶어보자.
expectations = new ExpectationsOn(IMethods.class);
mock = (IMethods) expectations.getMock();
mock = (IMethods) expectations.getMock();
MockExpections 라는 클래스로 합치는 것을 시도해보았으나 결국은 Mock 객체 호출이 필요했다. 여기까지는 별반 차이가 없어 보인다. 하지만, 실행 코드는 좀 간결하고 직관적으로 바뀌었다. 아래와 같은 코드였는데
mock.throwsNothing(true);
control.setReturnValue("Test");
control.setReturnValue("Test2");
control.replay();
assertEquals("Test", mock.throwsNothing(true));
assertEquals("Test2", mock.throwsNothing(true));
control.verify();
control.setReturnValue("Test");
control.setReturnValue("Test2");
control.replay();
assertEquals("Test", mock.throwsNothing(true));
assertEquals("Test2", mock.throwsNothing(true));
control.verify();
안 불러도 별 차이가 없는, verify()는 생략해버리고 Control보다는 '기대 값'이란 점을 강화했다. API 스타일은 Fluent Interface를 채용했다.
mock.throwsNothing(true);
expectations.returns("Test").returns("Test2").assert();
assertEquals("Test", mock.throwsNothing(true));
assertEquals("Test2", mock.throwsNothing(true));
ready 가 작위적인 느낌이 있지만, 익숙하지 않은 사람에게 replay 역시 큰 차이가 없다. 여기까지만 하고... 위키피디아의 Mock 객체에 대한 메모를 남겨둔다.
a mock object in its place:
- supplies non-deterministic results (e.g. the current time or the current temperature);
- has states that are difficult to create or reproduce (e.g. a network error);
- is slow (e.g. a complete database, which would have to be initialized before the test);
- does not yet exist or may change behavior;
- would have to include information and methods exclusively for testing purposes (and not for its actual task).













이올린에 북마크하기
이올린에 추천하기
