2017-11-16 4 views
0

내 웹 서비스의 메소드를 단위 테스트하는 데 어려움을 겪고 있습니다. 모든 메소드는 삽입 된 WebServiceContext를보고 userId를 가져와 사용자가 권한이 있는지 확인합니다. WebServiceContext를 조롱하는 방법을 알아 내려고 많은 시간을 보냈지 만, 내가 시도한 것에 상관없이 컨텍스트는 항상 null입니다.웹 서비스에 삽입 된 WebServiceContext를 모의하는 방법

최종 목표는 나머지 테스트 메소드의 실제 기능을 테스트 할 수 있도록 테스트 클래스에서 지정한 userId를 반환 할 수있게하는 것입니다.

이 방법의 대부분은 설치 얼마나의 옷을 벗었 버전은 :

@HandlerChain(file = "/handler.xml") 
@javax.jws.WebService (...) 
public class SoapImpl 
{ 
    @Resource 
    private WebServiceContext context; 

    public void methodUnderTest() 
    { 

     // context is NULL here - throws null pointer 
     Principal userprincipal = context.getUserPrincipal(); 

     String userId = userprincipal.getName(); 


     // Do some stuff - I want to test this stuff, but can't get here 
    } 

} 

이것은 내가 의존성 주입에 대한

@RunWith(MockitoJUnitRunner.class) 
@PrepareForTest(SoapImpl.class) 
public class SoapImplTest { 

    @Mock 
    WebServiceContext context; 

    @Mock 
    Principal userPrincipal; 

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

    @Test 
    public void testCreateOverrideRules() { 

     SoapImpl testImpl = new SoapImpl(); 

     when(context.getUserPrincipal).thenReturn(userPrincipal); 
     when(userPrincipal.getName()).thenReturn("testUser"); 

     testImpl.methodUnderTest(); 

     assertEquals(1,1); 
    } 

} 

내가 알고있는 상황과 테스트를 조롱을 시도하고 어떻게 생성자를 통해 컨텍스트를 전달하지만 컨텍스트가 @resource 주석을 통해 주입되므로 여기에서 수행 할 수 있는지 확신 할 수 없습니다. 생성자는 절대로 호출되지 않습니다. 나는 그것을 어떻게 구현할 것인지 완전히 이해하지 못합니다.

또한 WebServiceContext와 Principal은 인터페이스이므로 인스턴스화 할 수 없으므로 훨씬 더 혼란 스럽습니다. 누구든지 나를 도울 수 있습니까? WebServiceContext와 Principal을 어떻게 조롱하면 메소드의이 부분을 지나서 실제로 테스트하고 싶은 부분으로 넘어갈 수 있습니까?

UPDATE 아래의 코드와 같이 나는 @InjectMocks 주석을 사용하여 문제를 해결할 수 있었다 :

@RunWith(MockitoJUnitRunner.class) 
@PrepareForTest(SoapImpl.class) 
public class SoapImplTest { 

    @InjectMocks 
    private SoapImpl testImpl = new SoapImpl(); 

    @Mock 
    WebServiceContext context; 

    @Mock 
    Principal userPrincipal; 

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

    @Test 
    public void testCreateOverrideRules() { 

     when(context.getUserPrincipal).thenReturn(userPrincipal); 
     when(userPrincipal.getName()).thenReturn("testUser"); 

     testImpl.methodUnderTest(); 

     assertEquals(1,1); 
    } 

} 

답변

0

1)이 컨텍스트를 설정하는 생성자 또는 세터가 있어야 당신의 테스트중인 클래스. 그렇지 않다면이 정확한 이유에 대해 하나를 추가하고 싶을 것입니다.

2) WebServiceContext 또는 Principal을 인스턴스화 할 필요가 없습니다. 단순히 Mockito.mock (WebServiceContext.class) 및 Mockito.mock (Principal.class)을 사용하여 모의 객체를 만듭니다. 그런 다음 Mockito.when (mockWebServiceContext)를 추가하여 동작을 추가하십시오.

단위 테스트를 수행하는 경우 추가 메서드 나 통합이 아닌 테스트중인 메서드의 논리 만 테스트하려고합니다. 이것이 WebServiceContext와 Principal의 모의 인스턴스가 필요한 이유입니다. 당신은 통합 테스트 (아마)를 원하지 않습니다.

+0

. 나는 세터를 더했다. 그러나 나는 세터가 사적이기 때문에 문맥을 조롱 할 수 없다. 보안상의 이유로이 방법을 공개적으로 사용하고 싶지 않습니다. 이 문제를 해결하는 방법을 알고 있습니까? – mwelk11

+0

이상적으로는 생성자 기반 주입을 사용하고 WebServiceContext를 사용하는 공용 생성자 (setter 대신)를 사용하는 것이 좋습니다. 이렇게하면 SoapImpl 클래스는 변경되지 않습니다 (상태 비 저장 시스템의 원하는 특성). 그러나 세터 경로를 선택하는 경우 세터를 공개로 설정해야합니다. –

+0

그러면 Mock 객체로 생성자를 호출 할 수 있습니다. –