使用Mockito和PowerMock验证传递给静态方法的参数

Sam*_*Sam 5 java static-methods unit-testing mockito powermockito

我正在尝试测试void方法,但要验证它在调用它时传递给静态方法的参数。静态方法负责持久化这些参数。

class ProxyHandler {
  public void process(String str) {
    // parse the str and populate x, y, z
    PersistManager.proxy(x, y, z); 
  }
}
Run Code Online (Sandbox Code Playgroud)

下面的PersistManager包含我试图捕获其接收的参数的静态方法。

class PersistManager {
  public static void proxy(String x, String y, String z) {
    // persist the x, y, z
  }
}
Run Code Online (Sandbox Code Playgroud)

最后是我的测试类,测试ProxyHandler:

@RunWith(PowerMockRunner.class)
@PrepareForTest(PersistManager.class)
public class TestProxyHandler() {
   private ProxyHandler handler;

   @Before
   public void setUp() {
     handler = new ProxyHandler();
   }

   @Test
   public void testProxy() {
     PowerMockito.mockStatic(PersistManager.class);
     ArgumentCaptor<String> arg1 = ArgumentCaptor.forClass(String.class);
     ArgumentCaptor<String> arg2 = ArgumentCaptor.forClass(String.class);
     ArgumentCaptor<String> arg3 = ArgumentCaptor.forClass(String.class);

     handler.process("a long string");
     PowerMockito.verifyStatic(PersistManager.class, times(1));
     PersistManager.proxy(arg1.capture(), arg2.capture(), arg3.capture());
     assertEquals("x", arg1.getValue());
   }
}
Run Code Online (Sandbox Code Playgroud)

运行测试时,出现以下错误:

Wanted but not invoked PersistManager.proxy(
    null,
    null,
    null
);
Actually, there were zero interactions with this mock.
Run Code Online (Sandbox Code Playgroud)

我还注意到,如果将times(1)的值更改为任何其他值,则verifyStatic仍会通过。我究竟做错了什么?

kri*_*aex 4

很抱歉这么晚才回答这个问题,但我只是偶然发现它,因为我正在用 Powermockito 调查其他东西。我复制了您的情况如下(抱歉,我不喜欢默认包):

package de.scrum_master.stackoverflow.q49946922;

class PersistManager {
  public static void proxy(String x, String y, String z) {
    System.out.printf("Persisting %s, %s, %s%n", x, y, z);
  }
}
Run Code Online (Sandbox Code Playgroud)
package de.scrum_master.stackoverflow.q49946922;

public class ProxyHandler {
  public void process(String str) {
    String[] params = str.split(" ");
    PersistManager.proxy(params[0], params[1], params[2]);
  }
}
Run Code Online (Sandbox Code Playgroud)
package de.scrum_master.stackoverflow.q49946922;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.times;

@RunWith(PowerMockRunner.class)
@PrepareForTest(PersistManager.class)
public class ProxyHandlerTest {
  private ProxyHandler handler;

  @Before
  public void setUp() {
    handler = new ProxyHandler();
  }

  @Test
  public void testProxy() {
    PowerMockito.mockStatic(PersistManager.class);
    ArgumentCaptor<String> arg1 = ArgumentCaptor.forClass(String.class);
    ArgumentCaptor<String> arg2 = ArgumentCaptor.forClass(String.class);
    ArgumentCaptor<String> arg3 = ArgumentCaptor.forClass(String.class);

    handler.process("a long string");
    PowerMockito.verifyStatic(PersistManager.class, times(1));
    PersistManager.proxy(arg1.capture(), arg2.capture(), arg3.capture());
    assertEquals("a", arg1.getValue());
    assertEquals("long", arg2.getValue());
    assertEquals("string", arg3.getValue());
  }
}
Run Code Online (Sandbox Code Playgroud)

这工作完美无缺。您可能做错了什么,或者您未显示的代码存在问题。无需切换到 JMockit。

顺便说一句,我使用了 PowerMock 2.0.2、Mockito 2.23.0、JUnit 4.12、Java 8。