Вопрос по java, mockito, powermock – PowerMockito: получено исключение InvalidUseOfMatchersException при использовании насильственного статического метода соответствия

5

Когда я тестирую этот статический метод

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, Мои вопросы:

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. When I add the @PrepareForTest annotation to the test class and run the test, the junit makes no response. Why?

РЕДАКТИРОВАТЬ

Я пытался не использовать сопоставления аргументов, и получил

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:

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

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

at ...

Так что похоже из-заsomeMethod сам. Естьsynchronized блок в методе. Мне интересно, может ли Powermockito высмеивать такой метод или нет.

@DavidWallace Не бери в голову. Спасибо, что угодно. Kirin Yao
Кирин, мои извинения. Я удалил свой неправильный ответ. Dawood ibn Kareem
Когда ты сказал"PrepareForTest makes no response", это может объяснить точку"2. inside when() you don't call method on mock but on some other object", Проверьте банки на вашем пути к классам. Я добавил минимальный список обязательных JAR-файлов к моему ответу вместе с версиями, которые мне подходят. Brad

Ваш Ответ

4   ответа
1

Лучше поздно, чем никогда, строка ниже:

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

0

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.

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

Возможно, опубликуйте полный пример, чтобы помочь диагностировать, что происходит?

someMethod содержит синхронизированный код Может ли Powermockito высмеивать это? Kirin Yao
2

Попробуйте заменить isA () на другой вызов any () следующим образом

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

[EDIT]

Проверьте свою трассировку стека, когда получите исключение. Вы видите какие-либоNoClassDefFoundError сообщили? Я заметил, когда я не включилjavassist.jar в моем проекте я получил похожую ошибку с вами.

Я использую PowerMockito, и это банки, которые я добавил в новый проект для запуска кода, опубликованного @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 common-logging-1.1.1.jar

Всегда хорошая идея проверить, что вы используете совместимые версии JAR, а также проверить, есть ли какие-либо другие конфликтующие JAR-файлы в пути к классам ваших проектов.

Все еще не удалось :( Но PrepareForTest теперь в порядке. Спасибо. Kirin Yao
О боже, я только импортировал powermock-mockito-xxx.jar и mockito-all-xxx.jar. Я попытаюсь импортировать другие. Kirin Yao
Да, наличие синхронизированного метода не будет иметь отношения к этой проблеме. Я обновил свой ответ, убедитесь, что в вашем проекте установлены необходимые JAR-файлы.
Все еще выбрасывает то же исключение.someMethod содержит синхронизированный код Может ли Powermockito высмеивать это? Kirin Yao
-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. Попробуйте включить эти банки в сборку.

К сожалению, я использую Eclipse. Но все равно спасибо. Kirin Yao
powermock-api-mockito-1.4.11, powermock-api-support-1.4.11, powermock-core-1.4.11, powermock-module-junit4-1.4.11, powermock-module-junit4-common-1.4.11, mockito-all-1.9.0 Попробуйте включить эти банки вручную ...

Похожие вопросы