Во время тестов комплекта EasyMock сообщает, что ожидается 0 совпадений, 1 записано. - PullRequest
16 голосов
/ 19 февраля 2010

Итак, я уже некоторое время использую расширение класса 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, так что он не должен наследовать что-то откуда-то еще (не то, чтобы какой-то другой метод мог использовать его))

Итак, есть идеи?

Ответы [ 6 ]

11 голосов
/ 19 февраля 2014

Мне надоело видеть это с каждой новой устаревшей базой кода с EasyMock, с которой мне приходилось работать. Напишите один новый тест EasyMock по книге, и все внезапные случайные тесты начнут проваливаться из-за того, что Matchers никогда не регистрируются. Итак, я посмотрел, как EasyMock хранит эти Matchers. Он использует последний класс LastControl, в этом классе есть несколько локальных потоков, где хранятся разные вещи. Один из них был для Matchers. Удача в том, что там есть статический метод для извлечения всех Matchers из локального потока, который еще там. Так что это дало мне эту идею (с помощью коллеги, спасибо Свен, он хотел кредит)

/**
 * 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, выходит из этого класса, и вы будете уверены, что Matchers очищены. Обратите внимание, что это временное решение. Оскорбительные тесты должны были быть написаны с самого начала. Но если вам нужно пройти более 5000 тестов, это меньшее из двух зол. Я надеюсь, что это поможет людям!

4 голосов
/ 10 июня 2010

Несмотря на то, что это может быть ложное сообщение, вызванное «глупой» ошибкой EasyMock, оно также может быть связано с неправильным использованием EasyMock API.В моем случае сообщение возникло из этого теста 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 (), но я не проверял это экспериментально.

2 голосов
/ 29 августа 2011

Я только столкнулся с этой проблемой, и я думаю, что мне удалось разобраться.Для меня это было связано с предыдущим тестом (в другом классе), где я (неправильно) использовал сопоставление EasyMock в методе Assert.assertEquals.

Кажется, что EasyMock не мог пожаловаться на дополнительное совпадение, о котором сообщалось, пока не были вызваны первые методы.

2 голосов
/ 21 октября 2010

У меня было то же сообщение об ошибке.Я (случайно) использовал объявление isA () в вызове тестируемого класса

Т.е.

classUnderTest.callStateChanged(calls, isA(LoggingOnlyListener.class));

, когда имел в виду:

classUnderTest.callStateChanged(calls, new LoggingOnlyListener());

И этобыл тест ПОСЛЕ этого, который каждый раз терпел неудачу.

1 голос
/ 27 мая 2010

Какую версию Easymock вы используете?
Я прочитал пост о выпуске v.2.5.2 и предыдущие версии могут иметь

тупая ошибка при захвате

попробуйте использовать Easymock 2.5.2 +

1 голос
/ 25 марта 2010

Я столкнулся с подобной проблемой. Из того, что я заметил, даже возвращаемые методы сопоставляются с использованием Matchers. Таким образом, если ваш первый метод завершится неудачей по какой-либо причине, сопоставитель для возвращаемого совпадения все еще находится в стеке. Это может быть одной из причин, почему вы видите 1 записанное сопоставление, даже если ваш метод не принимает аргументов. По сути, первый вызов метода никогда не возвращал значение.

...