PowerMockito: got InvalidUseOfMatchersException when use matchers mocking static method

末鹿安然 提交于 2020-01-11 08:48:05

问题


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. 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.
  2. When I add the @PrepareForTest annotation to the test class and run the test, the junit makes no response. 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'. For example: when(mock.getArticles()).thenReturn(articles);

Also, this error might show up because:

  1. you stub either of: final/private/equals()/hashCode() methods. Those methods cannot be stubbed/verified.

  2. inside when() you don't call method on mock but on some other object.

at ...

So it seems due to the someMethod itself. There are synchronized block in the method. I'm wondering if Powermockito can mock that kind of method or not.


回答1:


Try replacing the isA() to another any() call like this

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? I noticed when I hadn't included the javassist.jar in my project I got a similar error to you.

I use PowerMockito and these are the jars I added to a brand new project to run the code that @Tom posted

  • powermock-mockito-1.4.10-full.jar
  • mockito-all-1.8.5.jar
  • javassist-3.15.0-GA.jar
  • junit-4.8.2.jar
  • common-logging-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.




回答2:


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




回答3:


  1. isA will always return null. This is by design, it is documented in the Javadoc for the isA() method. 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. The null value which is returned is not actually acted upon.

  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?




回答4:


<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. Try including these jars to the build.



来源:https://stackoverflow.com/questions/10828843/powermockito-got-invaliduseofmatchersexception-when-use-matchers-mocking-static

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!