简体   繁体   English

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

[英]PowerMockito: got InvalidUseOfMatchersException when use matchers mocking static method

When I'm testing this static method 当我测试这个静态方法时

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

with

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

I got InvalidUseOfMatchersException . 我得到了InvalidUseOfMatchersException My questions are: 我的问题是:

  1. Why I got this exception when all the arguments are using matchers? 当所有参数都使用匹配器时,为什么会出现此异常? How to solve it? 怎么解决? I have debugged it, found the isA(Log.class) returns null. 我调试了它,发现isA(Log.class)返回null。
  2. When I add the @PrepareForTest annotation to the test class and run the test, the junit makes no response. 当我将@PrepareForTest注释添加到测试类并运行测试时,junit没有响应。 Why? 为什么?

EDIT 编辑

I tried not to use argument matchers, and got 我试图不使用参数匹配器,并得到了

org.mockito.exceptions.misusing.MissingMethodInvocationException: when() requires an argument which has to be 'a method call on a mock'. org.mockito.exceptions.misusing.MissingMethodInvocationException:when()需要一个必须是'模拟上的方法调用'的参数。 For example: when(mock.getArticles()).thenReturn(articles); 例如:when(mock.getArticles())。thenReturn(articles);

Also, this error might show up because: 此外,此错误可能会显示,因为:

  1. you stub either of: final/private/equals()/hashCode() methods. 你存在以下任何一个:final / private / equals()/ hashCode()方法。 Those methods cannot be stubbed/verified. 这些方法无法进行存根/验证。

  2. inside when() you don't call method on mock but on some other object. 在when()中你不是在mock上调用方法而是在其他一些对象上调用方法。

at ... 在 ...

So it seems due to the someMethod itself. 因此似乎是由于someMethod本身。 There are synchronized block in the method. 方法中有synchronized块。 I'm wondering if Powermockito can mock that kind of method or not. 我想知道Powermockito是否可以嘲笑那种方法。

Try replacing the isA() to another any() call like this 尝试将isA()替换为另一个any()调用

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

[EDIT] [编辑]

Check your stacktrace when you get the exception. 收到异常后检查堆栈跟踪。 Are you seeing any NoClassDefFoundError reported? 您是否看到报告任何NoClassDefFoundError I noticed when I hadn't included the javassist.jar in my project I got a similar error to you. 我注意到当我没有在我的项目中包含javassist.jar ,我得到了类似的错误。

I use PowerMockito and these are the jars I added to a brand new project to run the code that @Tom posted 我使用PowerMockito,这些是我添加到一个全新项目中的罐子,用于运行@Tom发布的代码

  • powermock-mockito-1.4.10-full.jar powermock-的Mockito-1.4.10-full.jar
  • mockito-all-1.8.5.jar 的Mockito-ALL-1.8.5.jar
  • javassist-3.15.0-GA.jar Javassist进行-3.15.0-GA.jar
  • junit-4.8.2.jar JUnit的-4.8.2.jar
  • common-logging-1.1.1.jar 共记录-1.1.1.jar

Always a good idea to check that you're using compatible JAR versions, and also check if there are any other conflicting JARs in your projects classpath. 最好检查您是否使用兼容的JAR版本,还要检查项目类路径中是否存在任何其他冲突的JAR。

Better late than never, the line below: 迟到总比没有好,下面一行:

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

should be: 应该:

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

So, instead of invoking Mockito.when , one should invoke PowerMockito.when 所以,不应该调用Mockito.when ,而应该调用PowerMockito.when

  1. isA will always return null . isA将始终返回null This is by design, it is documented in the Javadoc for the isA() method. 这是设计的,它在isA()方法的Javadoc中有记录。 The reason for this is that null will always match the parameterized return type of class, which will always match the type of the argument in the stubbed method for which the isA() Matcher is used. 原因是null将始终匹配类的参数化返回类型,它将始终匹配使用isA()匹配器的存根方法中的参数类型。 The null value which is returned is not actually acted upon. 返回的null值实际上不会被执行。

  2. Seems to work fine for me. 似乎对我来说很好。 My complete test case: 我的完整测试用例:

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

Perhaps post a complete example to help diagnose what's going on? 也许发布一个完整的例子来帮助诊断正在发生的事情?

<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>

I hope your project is using maven. 我希望你的项目使用maven。 Try including these jars to the build. 尝试将这些罐子包含在构建中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM