验证PowerMock中的另一个静态方法是否调用了静态方法

时间:2014-01-29 21:43:22

标签: android mockito powermock android-testing

我有一个带有两个静态方法的Tool类,doSomething(Object)和callDoSomething()。这些名称很直观,因为callDoSomething将其调用委托给doSomething(Object);

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

我有一个Tool类的Test类,我想验证是否调用了doSomething(Object)(我希望以后也能进行Argument 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;
    }
  }
}

如果直接调用,则验证选择doSomething(Object)。我在上面评论了这段代码。验证在使用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类进行任何更改。我的问题是,如何验证从callDoSomething()调用doSomething(Object),以及在doSomething的param上执行一些参数匹配

2 个答案:

答案 0 :(得分: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()的两行。 (我在我的Tool.java版本中添加了一个简单的System.out.println("do something " + o);作为doNothing()的附加验证。)

答案 1 :(得分: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();

    }

<强>记住

如果您从不是doSomething()的其他方式拨打callDoSomething(),请不要忘记进行验证,您可以通过Tool.isFromCallDoSomethingMethod = false

来执行此操作

这是你想要的吗?