PowerMockito:使用matchers模拟静态方法时得到InvalidUseOfMatchersException

当我测试这个静态方法时

public class SomeClass { public static long someMethod(Map map, String string, Long l, Log log) { ... } } 

 import org.apache.commons.logging.Log; @RunWith(PowerMockRunner.class) //@PrepareForTest(SomeClass.class) public class Tests { @Test public void test() { ... PowerMockito.mockStatic(SomeClass.class); Mockito.when(SomeClass.someMethod(anyMap(), anyString(), anyLong(), isA(Log.class))).thenReturn(1L); ... } } 

我得到了InvalidUseOfMatchersException 。 我的问题是:

  1. 当所有参数都使用匹配器时,为什么会出现此exception? 怎么解决? 我调试了它,发现isA(Log.class)返回null。
  2. 当我将@PrepareForTest批注添加到测试类并运行测试时,junit没有响应。 为什么?

编辑

我试图不使用参数匹配器,并得到了

org.mockito.exceptions.misusing.MissingMethodInvocationException:when()需要一个必须是’模拟上的方法调用’的参数。 例如:when(mock.getArticles())。thenReturn(articles);

此外,此错误可能会显示,因为:

  1. 你存在以下任何一个:final / private / equals()/ hashCode()方法。 这些方法无法进行存根/validation。

  2. 在when()中你不是在模拟上调用方法而是在其他对象上调用方法。

在 …

因此似乎是由于someMethod本身。 方法中有synchronized块。 我想知道Powermockito是否可以嘲笑那种方法。

尝试将isA()替换为另一个any()调用

 Mockito.when(SomeClass.someMethod(anyMap(), anyString(), anyLong(), any(Log.class))).thenReturn(1L); 

[编辑]

收到exception后检查堆栈跟踪。 您是否看到报告过任何NoClassDefFoundError ? 我注意到当我没有在我的项目中包含javassist.jar ,我得到了类似的错误。

我使用PowerMockito,这些是我添加到一个全新项目中的jar子,用于运行@Tom发布的代码

  • powermock-的Mockito-1.4.10-full.jar
  • 的Mockito-ALL-1.8.5.jar
  • Javassist进行-3.15.0-GA.jar
  • JUnit的-4.8.2.jar
  • 共记录-1.1.1.jar

最好检查您是否使用兼容的JAR版本,还要检查项目类路径中是否存在任何其他冲突的JAR。

  1. isA将始终返回null 。 这是设计的,它在isA()方法的Javadoc中有记录。 原因是null将始终匹配类的参数化返回类型,它将始终匹配使用isA()匹配器的存根方法中的参数类型。 返回的null值实际上不会被执行。

  2. 似乎对我来说很好。 我的完整测试用例:

 import static org.mockito.Matchers.*; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.impl.SimpleLog; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; class SomeClass { public static long someMethod(final Map map, final String string, final Long l, final Log log) { return 2L; } } @RunWith(PowerMockRunner.class) @PrepareForTest(SomeClass.class) public class InvalidUseOfMatchersTest { @Test public void test() { // Mock the SomeClass' static methods, stub someMethod() to return 1 PowerMockito.mockStatic(SomeClass.class); Mockito.when(SomeClass.someMethod(anyMap(), anyString(), anyLong(), isA(Log.class))).thenReturn(1L); // null NOT is-a Log, uses default stubbing: returns 0 System.out.println(SomeClass.someMethod(null, null, 5L, null)); // SimpleLog passes is-a test, uses stubbed result: returns 1 System.out.println(SomeClass.someMethod(null, null, 7L, new SimpleLog("simplelog"))); } } 

也许发布一个完整的例子来帮助诊断正在发生的事情?

迟到总比没有好,下面一行:

 Mockito.when(SomeClass.someMethod(anyMap(), anyString(), anyLong(), isA(Log.class))).thenReturn(1L); 

应该:

 PowerMockito.when(SomeClass.someMethod(anyMap(), anyString(), anyLong(), isA(Log.class))).thenReturn(1L); 

因此,不应该调用Mockito.when ,而应该调用PowerMockito.when

  org.mockito mockito-all ${mockito.version}   org.powermock powermock-module-junit4 ${powermock.version} jar provided   org.powermock powermock-api-mockito ${powermock.version} jar provided  

我希望你的项目使用maven。 尝试将这些jar子包含在构建中。