2011-09-23 2 views
2

스프링 컨트롤러 메서드에 대한 junit 테스트를 만들려고하는데 다음 오류가 계속 발생합니다.봄철 JUnit 테스트

java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, 
or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, 
your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request. 
at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:123) 

필요한 두 가지를 추가했습니다. (각각 별도로 시도했습니다) 현재 내 web.xml에는

<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 

<listener> 
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> 
</listener> 

<filter> 
    <filter-name>requestContextFilter</filter-name> 
    <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class> 
</filter> 
    <filter-mapping> 
    <filter-name>requestContextFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

가 포함되어 있으며 테스트하려는 메소드는

@Controller 
@RemotingDestination 
public class MyController { 

public Response foo() 
    { 
//... 
     ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes(); 
     HttpSession httpSession = attr.getRequest().getSession(true); 
//... 
} 

행을 따르고 my junit 테스트는 단순히 myController.foo()를 호출하고 응답을 확인합니다. 그래서이 문제를 해결하기 위해 메소드에 전달할 mock 객체를 만들 수 없습니다.

그래서 내 질문에, 거기에 일부 구성 또는 트릭이 내 컨트롤러 메서드를 리팩터링하지 않고도이 실행하게됩니다 우연히 발견 할 수 있습니까?

답변

3

오류 메시지는 분명합니다. 불행히도 코드에는 약간의 재 작성이 필요합니다.

먼저 컨트롤러를 테스트하는 동안 (분명히) 웹 요청 안에 있지 않습니다. 그래서 RequestContextHolder.currentRequestAttributes()이 작동하지 않습니다.

public Response foo(@SessionAttribute("someSessionAttribute") int id) 

이 방법은 스프링 MVC를 :하지만 당신은 테스트가 코드 훨씬 더 다음과 같은 기술을 사용하여 읽을 수하기를 리팩토링 통과 할 수 있습니다 (당신이 일부 실제 속성을 얻기 위해 HTTP 세션을 필요로 가정) 자동으로 세션을 가져오고 웹 요청 안에 someSessionAttribute을로드합니다 (그리고 필요한 변환도 수행함). 그러나 컨트롤러를 테스트 할 때는 고정 된 매개 변수로 메소드를 호출하십시오. 요청/세션 인프라 코드가 없습니다. 더 청결한 (당신이 제공 한 foo의 두 줄은 전혀 필요하지 않음에 유의하십시오).

다른 해결책은 RequestScope을 수동으로 등록하는 것입니다. 예 : here을 참조하십시오. 이것은 조롱 된 요청 및 세션으로 코드를 수정하지 않고도 작동합니다.

+0

+1 Btw, 샘플 코드에 유형을 추가해야합니다. –

+0

고마워, 고쳐! –

+0

감사합니다. 미래에이 문제를 읽는 사람들에게 내 문제를 해결하기 위해 무엇을했는지 명확히하기 위해 - @SessionAttributes ("mySessionAttribute") 공용 클래스 AccountController {...}'를 사용했고 내 메소드는'public Response foo (@ModelAttribute ("mySessionAttribute") Object myObject) {...}' 장기적으로 내 상황에서 작동하는지 여부는 아직 알 수 없지만 현재로서는 효과가 있습니다. 희망이 다른 사람을 도와줍니다. – user960564