2014-01-29 1 views
0

두 개의 정적 메서드 doSomething (Object) 및 callDoSomething()이있는 Tool 클래스가 있습니다. 이름은 그 callDoSomething에서 직관적이다. doSomething (Object)에 대한 호출을 위임한다.정적 메서드가 PowerMock의 다른 정적 메서드에 의해 호출되었는지 확인

public class Tool 
{ 
    public static void doSomething(Object o) 
    { 
    } 
    public static void callDoSomething() 
    { 
    doSomething(new Object()); 
    } 
} 

나는 도구에 대한 테스트 클래스를하고 난 해봐요 (객체)가 호출 된 경우

@RunWith(PowerMockRunner.class) 
@PrepareForTest({ Tool.class }) 
public class ToolTest 
{ 
    @Test 
    public void toolTest() 
    { 
    PowerMockito.mockStatic(Tool.class); 
    Tool.callDoSomething();// error!! 
    //Tool.doSomething();// this works! it gets verified! 
    PowerMockito.verifyStatic(); 
    Tool.doSomething(Mockito.argThat(new MyArgMatcher())); 
    } 

    class MyArgMatcher extends ArgumentMatcher<Object> 
    { 
    @Override 
    public boolean matches(Object argument) 
    { 
     return true; 
    } 
    } 
} 

있는 호텔 상품을 확인 (내가 미래에 너무 일치 인수를하고 싶어) 확인하고 싶습니다 doSomething (Object) 직접 호출되는 경우. 위의 코드를 주석으로 처리했습니다. verify는 callDoSomething을 사용할 때 doSomething (Object)을 선택하지 않습니다 (위 코드 참조). 위 코드를 실행하면 다음과 같은 오류 로그가 표시됩니다.

Wanted but not invoked tool.doSomething(null); 

However, there were other interactions with this mock. 
    at org.powermock.api.mockito.internal.invocation.MockitoMethodInvocationControl.performIntercept(MockitoMethodInvocationControl.java:260) 
    at org.powermock.api.mockito.internal.invocation.MockitoMethodInvocationControl.invoke(MockitoMethodInvocationControl.java:192) 
    at org.powermock.core.MockGateway.doMethodCall(MockGateway.java:105) 
    at org.powermock.core.MockGateway.methodCall(MockGateway.java:60) 
    at Tool.doSomething(Tool.java) 
    at ToolTest.toolTest(ToolTest.java:22) 
... [truncated] 

Tool 클래스를 변경하지 마십시오.

public class Tool{ 

    public static boolean isFromCallDoSomethingMethod= false; 







    public static void doSomething(Object o){ 

    } 








    public static void callDoSomething() { 

     doSomething(new Object()); 

     isFromCallDoSomethingMethod= true; 

    } 








} 

당신은 할 수 있습니다 내 질문은 내가

답변

1

정적 스파이 (부분 모의)를 사용하려는 것처럼 들립니다. 정적 조롱에 대해 이야기 section of the PowerMock documentation 쉽게 놓칠 수있는 두 번째 글 머리 기호의 메모가 있습니다

에,

주 (특정 방법을 모의 PowerMockito.spy (클래스)를 사용)하여 예를 들어 실제로 조롱하는 것이 아니라 단지 메서드를 확인하는 것입니다. 미묘하지만 중요한 차이가 있습니다. 당신이 호출 할 doSomething(Object)하지 않으려면이 같은 것을 할 필요가 거라고 :

@Test 
public void toolTest() { 
    PowerMockito.spy(Tool.class); //This will call real methods by default. 

    //This will suppress the method call. 
    PowerMockito.doNothing().when(Tool.class); 
    Tool.doSomething(Mockito.argThat(new MyArgMatcher())); 

    Tool.callDoSomething(); 

    //The rest isn't needed since you're already mocking the behavior 
    //but you can still leave it in if you'd like. 
    PowerMockito.verifyStatic(); 
    Tool.doSomething(Mockito.argThat(new MyArgMatcher())); 
} 

을 여전히 방법은 비록 발사 할 경우에, 다만 doNothing()의 두 줄을 제거합니다. (doNothing()의 추가 확인으로 간단한 버전 System.out.println("do something " + o);을 Tool.java에 추가했습니다.

+0

좋은 선생님, 고마워요. – sudocoder

0

당신이 당신의 유효성 검사를 할 수 있습니다) 해봐요 (객체)가 callDoSomething (호출 된 검증뿐만 아니라 해봐요의 PARAM 일부 인수 매칭을 수행 할 수있는 방법이다 로 검증을 수행

if(Tool.isFromCallDoSomethingMethod){ 

     //you called doSomething() from callDoSomething(); 

    } 

기억

는 CA 경우 유효성 검사를 수행하는 것을 잊지 마세요 이 callDoSomething()이 아닌 다른 방법으로 보내면 Tool.isFromCallDoSomethingMethod = false

이 무엇입니까?

+0

의견을 보내 주셔서 감사합니다. Tool 클래스 변경을 피하고 싶습니다. 이전에 언급 했어야했습니다. – sudocoder

관련 문제