Во время тестов на выборку EasyMock заявляет, что 0 ответных матчей ожидается 1 запись
Итак, я уже некоторое время использую расширение класса EasyMock. Внезапно я получаю это исключение, но только когда я запускаю весь набор тестов:
java.lang.IllegalStateException: 0 matchers expected, 1 recorded.
at org.easymock.internal.ExpectedInvocation.createMissingMatchers(ExpectedInvocation.java:42)
at org.easymock.internal.ExpectedInvocation.<init>(ExpectedInvocation.java:34)
at org.easymock.internal.ExpectedInvocation.<init>(ExpectedInvocation.java:26)
at org.easymock.internal.RecordState.invoke(RecordState.java:64)
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:24)
at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:56)
at org.easymock.classextension.internal.ClassProxyFactory$1.intercept(ClassProxyFactory.java:74)
at com.protrade.soccersim.data.emulator.matrix.PositionCategoryMatrix$$EnhancerByCGLIB$$c5298a7.getPossession(<generated>)
at com.protrade.soccersim.data.emulator.stats.team.PossessionCalculatorUnitTest.testDeterminePossessionHomeWin(PossessionCalculatorUnitTest.java:45)
Используемый код - это маленькая красавица (немного обрезанная):
@Before
public void setUp() throws Exception {
homeTeam = createMock( PositionCategoryMatrix.class );
awayTeam = createMock( PositionCategoryMatrix.class );
...
}
@Test
public void testDeterminePossessionHomeWin() {
expect(homeTeam.getPossession()).andReturn( 0.15151515 );
expect(awayTeam.getPossession()).andReturn( 0.01515152 );
replay( homeTeam, awayTeam );
...
}
Исключение возникает при первом ожидании. И это действительно не имеет смысла. В нем говорится, что он получает совпадение, но метод даже не принимает аргумента. И довольно странно это только во время тестовых комплектов! Я создаю новый макет в @Before, поэтому он не должен наследовать что-либо из другого места (не для того, чтобы какой-либо другой метод имел на нем совпадение)
Итак, любые идеи?
Ответы
Ответ 1
Мне было очень надоело это видеть с каждой новой базой кода с EasyMock, с которой мне приходилось работать. Напишите один новый тест EasyMock в книге, и все неожиданные случайные тесты начнут терпеть неудачу из-за того, что Matchers не были захвачены. Поэтому я пошел посмотреть, как EasyMock хранит этих Матчи. Он использует последний класс LastControl, в этом классе есть несколько threadlocals, где хранятся разные вещи. Один из них был для Матчи. У Luck есть то, что есть статический метод, чтобы вытащить всех Матчи из threadlocal, где еще там. Так что это дало мне эту идею (с помощью коллеги, спасибо Свену, он хотел получить кредит)
/**
* Base class to make sure all EasyMock matchers are cleaned up. This is not pretty but it will work
*
* @author N069261KDS
*
*/
public class BaseTest {
@Before
public void before(){
LastControl.pullMatchers();
}
@After
public void after(){
LastControl.pullMatchers();
}
}
Прежде всего, пусть ваш тест, который терпит неудачу с ошибкой Matchers, распространяется из этого класса, и вы убедитесь, что Matches очищены. Обратите внимание, что это ВОПРОС. В первую очередь должны были быть написаны оскорбительные тесты. Но если вам нужно пройти через 5000+ тестов, это меньше двух зол. Надеюсь, это поможет людям!
Ответ 2
Хотя верно, что это может быть ложным сообщением в результате "глупых" ошибок EasyMock, также очень вероятно, что это связано с неправильным использованием API EasyMock. В моем случае сообщение возникло из этого теста JUnit 3.8 (и, как и вы, это произошло только тогда, когда я провел весь набор тестов и только через Maven, а не Eclipse):
public void testSomething() {
// Set up
MyArgumentType mockArg = (MyArgumentType) EasyMock.anyObject(); // bad API usage
// Invoke the method under test
final String result = objectUnderTest.doSomething(mockArg);
// Verify (assertions, etc.)
...
}
Вместо использования anyObject() я должен был использовать createMock (MyArgumentType.class) или один из его вариантов. Я не знаю, что я думал, я написал миллионы этих тестов и правильно использовал API.
Запутанный бит заключается в том, что тест, который терпит неудачу с сообщением "неправильное количество совпадений", не обязательно (или когда-либо?) тот, в котором вы неправильно использовали API. Это может быть первый тест, выполненный после багги, который содержит метод replay() или verify(), но я не проверил это экспериментально.
Ответ 3
У меня было такое же сообщение об ошибке. Я был (случайно) с использованием объявления isA() в вызове тестируемого класса
т.е.
classUnderTest.callStateChanged(calls, isA(LoggingOnlyListener.class));
когда я имел в виду:
classUnderTest.callStateChanged(calls, new LoggingOnlyListener());
И это был тест ПОСЛЕ этого, который терпел неудачу каждый раз.
Ответ 4
Я просто столкнулся с этой проблемой, и я думаю, мне удалось это понять. Для меня это было связано с предыдущим тестом (это в другом классе), где я был (неправильно) с использованием помощника EasyMock в методе Assert.assertEquals.
Кажется, EasyMock не может жаловаться на дополнительный ответчик, до тех пор, пока первые не ожидали, что методы будут вызваны.
Ответ 5
У меня возникает аналогичная проблема. Из того, что я наблюдал, даже возвращает метод, используя Matchers. Поэтому, если ваш первый метод не удается по какой-либо причине, совпадение для совпадения возврата все еще находится в стеке. Это может быть одной из причин, по которой вы видите, что 1 бит записывается, даже если ваш метод не принимает никаких аргументов. В принципе, первый вызов метода никогда не возвращал значение.
Ответ 6
Какую версию Easymock вы используете?
Я прочитал post об освобождении версии 2.5.2, а в предыдущих версиях может быть
глупая ошибка при захвате
попробуйте использовать Easymock 2.5.2 +