2014-01-29 1 views
0

У меня есть класс Tool с двумя статическими методами, doSomething (Object) и callDoSomething(). Имена интуитивно понятны в том, что callDoSomething делегирует свой вызов doSomething (Object);Убедитесь, что статический метод был вызван другим статическим методом в PowerMock

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

У меня есть класс Test для инструмента, и я хотел бы проверить, если был назван йоЗотеЬЫпд (Object) (я хочу сделать аргумент Matching тоже в будущем)

@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; 
    } 
    } 
} 

Verify подхватывает doSomething (Object), если он вызван напрямую. Я прокомментировал этот код выше. Verify НЕ забирает doSomething (Object) при использовании callDoSomething (это код, показанный выше). Это мой журнал ошибок при запуске кода выше:

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] 

Я хотел бы избежать внесения каких-либо изменений в класс инструмента. Мой вопрос, как я могу проверить йоЗотеЬЫпд (Object) был вызван из callDoSomething(), а также выполнить некоторые сопоставления аргументов по парам DoSomething в

ответ

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(). (Я добавил System.out.println("do something " + o); в мою версию Tool.java в качестве дополнительной проверки doNothing().)

+0

хорошо сэр, спасибо. – sudocoder

0

Вы можете сделать свою проверку с этим:

public class Tool{ 

    public static boolean isFromCallDoSomethingMethod= false; 







    public static void doSomething(Object o){ 

    } 








    public static void callDoSomething() { 

     doSomething(new Object()); 

     isFromCallDoSomethingMethod= true; 

    } 








} 

Вы можете сделать проверку, как:

if(Tool.isFromCallDoSomethingMethod){ 

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

    } 

ПОМНИТЕ

не забудьте сделать проверку, если вы ча ll doSomething() с другого пути, который не от callDoSomething(), вы можете сделать это с помощью ussing Tool.isFromCallDoSomethingMethod = false

Это то, что вы хотите?

+0

Спасибо за ваше предложение! Я бы хотел избежать изменения класса Tool, я должен был упомянуть об этом ранее. – sudocoder