2017-04-07 6 views
0

질문 1 : CXF JAX-RS 서비스 단점 테스트를하는 동안 모의 (또는 실제) HttpServletResponse를 삽입하려면 어떻게해야합니까?단위 테스트 중 모의 HttpServletResponse

package services.example; 

import org.springframework.http.MediaType; 
import javax.servlet.http.HttpServletResponse; 
import javax.ws.rs.GET; 
import javax.ws.rs.POST; 
import javax.ws.rs.PUT; 
import javax.ws.rs.Path; 
import javax.ws.rs.PathParam; 
import javax.ws.rs.Produces; 
import javax.ws.rs.core.Context; 

@RestController 
@Path("/base") 
@Produces(MediaType.APPLICATION_JSON_VALUE); 
public class ExampleService { 

    @Autowired 
    SomeInjectedService injectedService; 

    @POST 
    @Path("/endpoint") 
    public Object testEndpoint(Object exampleInput, @Context HttpServletResponse response) { 
    if (exampleInput.someMethod != null) { 
     // Exception thrown here during tests, response is null!!! 
     response.setStatus(301); 
     return exampleInput; 
    } 

    return new injectedService.returnOutputFromInput(exampleInput); 
    } 
} 

테스트 클래스 : 우리의 서비스가 설치되는 방법

예 (I 비 테스트 구조를 변경하는 통제/권한이 없습니다주의)

package test.services.example 

// A gazillion imports. Mockito, JUnit, Hamcrest, Javax.ws.rs, org.apache.cxf, Jackson providers. 

public class testExampleService { 

    @Mock 
    private HttpServletResponse mockResponse; // Should I do this? 

    @Mock 
    SomeInjectedService mockInjectionService; 

    @InjectMocks 
    ExampleService service = new ExampleService(); 

    @Before 
    public void setUpStuff() { 
    MockitoAnnotations.initMocks(this); 

    JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean(); 
    sf.setResourceClasses(ExampleService.class); 

    List<Object> providers = new ArrayList<Object>; 
    JacksonJsonProvider provider = new JacksonJsonProvider(); 
    providers.add(provider); 

    sf.setProviders(providers); 

    sf.setResourceProvider(ExampleService.class, new SingletonResourceProvider(service, true)); 
    sf.setAddress("local://someuri"); 

    // This is where I'm trying to set up my injected Response context. Help? 
    sf.setInvoker(new Invoker() { 
     Invoker jarsInvoker = new JAXRSInvoker(); 

     @Override 
     public Object invoke(Exchange exchange, Object o) { 
     // What goes in here? I've seen an example for setting a mock 
     // Request context, but no for a Response. Here's my current 
     // (broken) attempt to do this... 
     exchange.getInMessage().put(AbstractHTTPDestination.HTTP_RESPONSE, mockResponse); 
     return jarsInvoker.invoke(exchange, o); 
     } 
    }); 
    } 

    @Test 
    public void testEndpointShouldReturn301() { 
    List<Object> providers = new ArrayList<Object>(); 
    JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider(); 
    providers.add(provider); 

    WebClient client = WebClient.create("local://someuri", providers); 
    WebClient.getConfig(client) 
      .getRequestContext() 
      .put(LocalConduit.DIRECT_DISPATCH, Boolean.TRUE); 

    // Exception thrown here, Response context doesn't get injected! 
    client.path("/base/endpoint"); 
    SomeTestObject obj = new SomeTestObject(); 
    Response response = client.type(MediaType.APPLICATION_JSON).post(obj); 

    // Never gets run because an exception was thrown :(
    assertThat(response.getStatus(), is(301)); 
    } 

} 

이 난 것을 가능 여기에 몇 가지 잘못된 일을하고 있지만, 내 엔드 포인트에 HttpServletResponse를 적절히 주입하기 위해 내 사용자 정의 Invoker 내부로 들어가는 올바른 "마술"이 필요하기를 바라고 있습니다. 주입 된 Context가없는 엔드 포인트에서 사용자 정의 호출기 비트를 제거하면 테스트가 올바르게 작동한다는 점을 유의할 것입니다.

답변

0

당신은 생성자 예 서비스를 초기화하지 않아도, 그냥이 유지 :

@InjectMocks 
ExampleService service; 

당신이 @Path ("/ 엔드 포인트")를 테스트하려면, 그것은 당신이하지만 이상한 않는 옳은 일이다 . 응답에 대한

@Test 
    public void testEndpointShouldReturn301() { 
    service.testEndpoint(someObject, mockResponse); 
    assertThat(response.getStatus(), is(301)); 
    } 
+0

감사합니다,하지만 테스트의 목적은 주어진 엔드 포인트에 대한 REST 호출이 예상되는 콜백 함수 안타 있는지 확인하는 것입니다 : 당신은 당신의 코드를 테스트하려면 , 그냥 같이 할. 테스트 중에는 - 내 예제에서 -/endpoint에 대한 POST가 항상 testEndpoint() 메소드를 트리거하는지 확인하는 것이 중요합니다. – Wrinn