Spring에서 단위테스트시 객체 주입 쉽게 하기 ReflectionInjector 프로그래밍

Spring Framework에서 어노테이션 기반의 객체 주입(@Resource, @Autowired)이 가능해지면서 생긴 변화가 하나 있다. 바로, Settter/Getter 메소드를 만들지 않게 된다는 점이다.

뭐 그건 좋은데, 그에 따라 부차적으로 딸려오는 문제가 하나 있다. 바로 단위테스트시에 private 필드에 대한 객체 주입(Injection)이 복잡해 진다는 점이다. Spring의 경우 이에 대한 해법으로 ReflectionTestUtils 라는 것을 제공해주고 있다.

그런데 ReflectionTestUtils를 사용하면 코드가 길고 복잡해진다. 단위 테스트 클래스의 코드가 아래와 같은 형태가 될 것이다.

...
ReflectionTestUtils.setField(articleService, "articleDao", articleDao);
ReflectionTestUtils.setField(articleService, "commentDao", commentDao);
...


그 외에도 리팩토링시에 "articleDao", "commentDao" 등의 문자열은 리팩토링이 안 된다는 문제도 함께 있다.

이게 은근히 짜증나는 일인지라 해결책을 찾아야지 찾아야지.. 하면서 미루고 있다가 ReflectionInjector 라는 간단한 유틸리티 클래스를 만들어서 처리해보았다. ReflectionInjector에서 관련 소스를 받을 수 있다.

ReflectionInjector를 사용하면 소스가 아래와 같은 형태가 된다.

import static kr.pe.kwonnam.reflectioninjector.ReflectionInjectorUtils.injector;
...
injector(articleService).set(articleDao)
                     .set(commentDao)
                     .set("userDao", userDao)
                     .set(SearchEngineDao.class, searchEngineDao);

불필요하게 소스가 길어지는 것을 막으려고 Method Chain을 할 수 있게 하였다.

기본적으로는 자동으로 타입 매칭을 해서 필드 객체를 주입하지만, 필드의 타입과 필드의 이름을 명시하는 것도 가능하게 해 두었다. 사실 이 중에서 Class 타입을 명시해서 주입하는 걸 얼마나 쓸지는 의문이긴 하다.


그리고 덤으로 별로 필요할 가능성이 적긴 하지만 필드의 값을 가져오는 것(Getter)도 가능하게 만들어 두었다.

혹시 오류가 있다면 ReflectionInjector에 있는 소스 안의 이메일로 신고해 주면 감사.

핑백

덧글

  • 몽몽이 2012/01/08 17:25 #

    Spring이란걸 요즘 공부하고 있는 사람인데...
    근본적으로는 DI를 프레임웍이 아니라 JVM에서 처리해야 맞을 것 같아요.
    모든게 다 거기서부터 복잡해지는 듯.
※ 로그인 사용자만 덧글을 남길 수 있습니다.