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

时间:2012-05-31 07:01:09

标签: java mockito powermock

当我测试这个静态方法时

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. 当所有参数都使用匹配器时,为什么会出现此异常?怎么解决?我调试了它,发现isA(Log.class)返回null。
  2. 当我将@PrepareForTest注释添加到测试类并运行测试时,junit没有响应。为什么?
  3. 修改

    我尽量不使用参数匹配器,并且

      

    org.mockito.exceptions.misusing.MissingMethodInvocationException:   when()需要一个必须是'对mock进行方法调用'的参数。   例如:       当(mock.getArticles())thenReturn(文章);

         

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

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

    2.   
    3. 在()内部,你不是在模拟上调用方法,而是在其他一些对象上调用方法。

    4.         

      at ...

    所以看起来似乎是someMethod本身。方法中有同步块。我想知道Powermockito是否可以嘲笑那种方法。

4 个答案:

答案 0 :(得分:2)

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

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

<强> [编辑]

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

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

  • powermock-的Mockito-1.4.10-full.jar
  • 的Mockito-全1.8.5.jar
  • 了Javassist-3.15.0-GA.jar
  • 的junit-4.8.2.jar
  • 共测井1.1.1.jar

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

答案 1 :(得分:1)

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

Batch   code
_____________
1        A
1        B
1        C
1        D
2        B
2        B
2        C
2        D

应该是:

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

答案 2 :(得分:0)

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

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

  3. 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")));
        }
    }

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

答案 3 :(得分:-1)

<dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-all</artifactId>
        <version>${mockito.version}</version>
    </dependency>
    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-module-junit4</artifactId>
        <version>${powermock.version}</version>
        <type>jar</type>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-api-mockito</artifactId>
        <version>${powermock.version}</version>
        <type>jar</type>
        <scope>provided</scope>
    </dependency>

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