[초급][테스팅] abstract class에 있는 필드 클래스 Injection은 어떻게 하면되나요?

1,202 views
Skip to first unread message

김 준영

unread,
Apr 26, 2012, 6:01:49 AM4/26/12
to ks...@googlegroups.com
안녕하세요. 스프링 초급 개발자입니다.

abstract class에 있는 필드 클래스가 본 구현체에서는 스프링 컨테이너?에서 injection받아서 구현 로직을 채웠는데요.

해당 abstract class를 구현한 클래스를 테스트를 하다가 abstract class에 있는 이 필드 클래스가 inject이 안되어서 문제를 겪고 있습니다.

물론, 테스트 클래스에도 똑같이 @Autowired를 통해 해당 구현 클래스를 가져오면 정상적으로 작동이 됩니다.
하지만, 이것이 데이터베이스와 연결이 되어있어서 이벤트가 건너가지 않았으면 해요.

구현이 어떻게 되어있냐하면요.

public abstract class DefaultHandler implements HandlerInteface {
@Autowired
private marshallerManager;

public void processXml(String xml) {
myDTO dto = getDTO(xml);
processDTO(dto);
}

public myDTO getDTO(String xml) {
marshallerManager.read(myDTO.class, xml);
}
}

public class EventHandler extends DefaultHandler {
...

@Override
public void processDTO(myDTO dto) {
// my logic in here
}

...
}


public class EventHandlerTest {
private EventHandler handler;
@Autowired
private EventHandler wiredHandler;

@Before
public void before() {
handler = new EventHandler();
}

@Test
public void testHandler_marshallerManager를_어떻게_injection_시킬수있을까요() {
handler.processXml(xml); // <---- nullpoint exception (marshallerManager가 null이까요.)
}

@Teset
public void testHandler_Autowired사용하면_적상적으로_작동이되요() {
handler.processXml(xml); // <--- 잘되요.
}
}


어떻게 해결할 수 있을가요?
도움 부탁드립니다.

윤재진

unread,
Apr 26, 2012, 6:57:01 AM4/26/12
to ks...@googlegroups.com

Test을 하실려면 Applicationcontext을 직접 선언해서 주입을 하시던지

스프링 test 어노테이션 context을 선언해서 주입하시는 방법이나

Mokito 이나 easymock으로 mockup 객체을 만들어서 주입시키고 테스트을 하셔야 됩니다

핸드폰에서 보냄

2012. 4. 26. 오후 7:01에 "김 준영" <june...@gmail.com>님이 작성:
--
Google 그룹스 'Korea Spring User Group' 그룹에 가입했으므로 본 메일이 전송되었습니다.
이 그룹에 게시하려면 ks...@googlegroups.com(으)로 이메일을 보내세요.
그룹에서 탈퇴하려면 ksug+uns...@googlegroups.com로 이메일을 보내주세요.
더 많은 옵션을 보려면 http://groups.google.com/group/ksug?hl=ko에서 그룹을 방문하세요.

최영목

unread,
Apr 26, 2012, 4:56:49 PM4/26/12
to ks...@googlegroups.com
저도 윤재진님 말씀에 동의합니다.

그리고 저는 보통 테스트용 구현체(즉, abstract 클래스를 상속받고 실제 오버라이드는 비워두는 형태의 클래스)를 만든 후 applicationContext-test.xml과 같이 테스트용 xml을 만들어서 처음에 설명하신 테스트케이스의 형태로 테스트를 진행합니다. ^^

2012년 4월 26일 오후 7:57, 윤재진 <spyrog...@gmail.com>님의 말:

Sanghyuk Jung

unread,
Apr 26, 2012, 6:01:52 PM4/26/12
to ks...@googlegroups.com
marshallerManager가 private인데 setter가 없네요. private field로 field injection을 했을때 application context없이 테스트용 객체를 어떻게 주입할것인가에 대한 질문으로 이해했습니다.

이럴 때는 private에서 protected나 package private으로 바꿔주는 것도 방법입니다. ReflectionTestUtils를 쓰는 방법도 가능하구요.

ReflectionTestUtils.setField(eventHandler, " marshallerManager ", mockMarshallerManager ); 

 개인적으로는 그냥 setter를 만들거나 package private으로 선언하는 방법을 선호합니다.

 그리고 테스트용 객체에서 재현해줘야하는 동작이 다양하다면 mock library를 사용하는 것보다 테스트 전용 구현을 만드는 것이 더 편한 경우도 있습니다.

2012년 4월 27일 오전 5:56, 최영목 <davi...@nextree.co.kr>님의 말:

김 준영

unread,
Apr 29, 2012, 8:45:38 PM4/29/12
to ks...@googlegroups.com
많은 분의 답변 감사합니다. 

상혁님. 
marshallerManager는 autowired 필드라 setter 없이 바로 사용했습니다.

Mockito사용법도 이번 기회가 공부하게 되었습니다. 
Mockito + DummyCreator 써서 랜더머 인자사용해서 테스트 정상적으로 수행할 수 있었습니다. 

감사합니다.

2012. 4. 27., 오전 7:01, Sanghyuk Jung 작성:

Sanghyuk Jung

unread,
Apr 29, 2012, 8:52:09 PM4/29/12
to ks...@googlegroups.com
아, private field + @Autowired도 저도 많이 봐와서, 크게 이상하게 생각하지는 않습니다 ^^; ReflectionTestUtils를 쓰면 그런 경우도 주입할수 있지만, 필드명을 스트링으로 지정해줘야해서 refactoring에 취약한 등의 단점이 있어서 개인적으로는 setter나 constructor, package private field를 선호한다는 정도의 의견이였습니다~

암튼 해결하셔서 다행이구요~ '랜더머 인자'가 어떤 것인지가 살짝 궁금해졌네요 ^^;


2012년 4월 30일 오전 9:45, 김 준영 <june...@gmail.com>님의 말:

김 준영

unread,
Apr 29, 2012, 9:26:54 PM4/29/12
to ks...@googlegroups.com
오타에요 ^^

DummyCreator라는 라이브러리 사용해서 Mockito로 생성한 인스턴스에 필드들에 랜덤 데이터를 채웠는데요. 

'랜덤 인자'를 언급해드린다는게 오타가 났습니다. ^^

라이브러리는 아래 url에서 확인하실 수 있습니다.



2012. 4. 30., 오전 9:52, Sanghyuk Jung 작성:
Reply all
Reply to author
Forward
0 new messages