Я работаю над модульным тестированием моего Java-приложения ..
Моя цель - использовать Powermock для создания шпиона на экземпляре класса BOProcessor. BOProcessor имеет метод окончательной пустоты; Я настрою своего шпиона на выдачу исключения при вызове этого метода. Я также буду издеваться над MyDao в этом же тесте, но издеваться над этим классом просто. Затем смоделированный MyDao будет передан в экземпляр MyDaoService с именем classUnderTest. Затем я сделаю утверждения против classUnderTest.
Всякий раз, когда я пытаюсь настроить описанный выше сценарий, Powermock (или Mockito?) Выдает исключение InvalidUseOfMatchersException, когда я настраиваю doThrow
в своем шпионе. Странно, но это исключение выдается только тогда, когда за ожиданием doThrow
следует вызов classUnderTest. Если я удаляю более поздний вызов classUnderTest, ожидание работает нормально. Даже страннее - classUnderTest даже не использует шпиона, который выдает ошибку!
Это весь мой тестовый код, описанный выше. Чтобы подчеркнуть проблему, я удалил весь код, не связанный напрямую. (Я даже удалил всю цель этого теста.)
package my.package;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doThrow;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.spy;
import org.junit.Test;
public class WhatAmIDoingWrong {
@Test
public void whatAmIDoingWrong() {
MyDao mockedDao = mock(MyDao.class);
BOProcessor processor = new BOProcessor();
BOProcessor mockedProcessor = spy(processor);
MyDaoService classUnderTest = new MyDaoService(mockedDao);
doThrow(new Exception()).when(mockedProcessor).process(any(FakeBusinessObject.class));
classUnderTest.interactWithDao();
}
}
Вот исключение - выброшенное (по иронии судьбы) из строки doThrow
моего тестового кода - которое я пытаюсь решить.
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
0 matchers expected, 1 recorded:
-> at my.package.WhatAmIDoingWrong.whatAmIDoingWrong(WhatAmIDoingWrong.java:21)
This exception may occur if matchers are combined with raw values:
//incorrect:
someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
//correct:
someMethod(anyObject(), eq("String by matcher"));
For more info see javadoc for Matchers class.
at my.package.MyDaoService.interactWithDao(MyDaoService.java:33)
at my.package.WhatAmIDoingWrong.whatAmIDoingWrong(WhatAmIDoingWrong.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)
Вот классы, использованные в моем тесте. Напомним, что MyDaoService с именем classUnderTest даже не знает о шпионе BOProcessor; это работает только против издевательства над MyDao. Но ожидания шпиона BOProcessor не оправдываются, только если вызывается classUnderTest.
public class BOProcessor {
public final void process(FakeBusinessObject bar) {}
}
public class FakeBusinessObject {
}
import java.util.Collections;
import java.util.List;
public class MyDao {
public MyDao() {}
public List<String> getAllData(){
return Collections.emptyList();
}
}
public class MyDaoService {
private MyDao applicationDao;
public MyDaoService(MyDao applicationDao) {
this.applicationDao = applicationDao;
}
public synchronized void interactWithDao() {
applicationDao.getAllData();
}
}
Я использую JUnit 4.12, Mockito 1.10.19 и Powermock 1.7.4. Проект работает Spring 4.3.12RELEASE с включенным весенним тестом.
Почему Powermock выдает это исключение? Я правильно не использую any
Matcher? С какой стати это исключение возникает только тогда, когда позже вызов взаимодействует с другим макетом?
Спасибо за помощь!