EasyMock 3.0, насмешливый класс выдает java.lang.IllegalStateException: нет последнего вызова для макета

Выполнение следующего модульного теста вызывает исключение: java.lang.IllegalStateException: нет последнего вызова доступного макета.


import org.easymock.*;
import org.junit.*;

public class MyTest {

    @Test
    public void testWithClass() {
        Thread threadMock = EasyMock.createMock(Thread.class);
        EasyMock.expect(threadMock.isAlive()).andReturn(true);
    }
}

Я не уверен, что я делаю неправильно, и не могу найти хороших примеров в Интернете. Как вы издеваетесь над классом, используя EasyMock 3.0. Что не так с приведенным выше модульным тестом? Любая помощь будет принята с благодарностью.

Мой проект включает следующие зависимости maven

<dependency>
   <groupId>org.easymock</groupId>
   <artifactId>easymock</artifactId>
   <version>3.0</version>
   <scope>test</scope>
</dependency>
<dependency>
   <groupId>cglib</groupId>
   <artifactId>cglib-nodep</artifactId>
   <version>2.2</version>
   <scope>test</scope>
</dependency>
<dependency>
   <groupId>org.objenesis</groupId>
   <artifactId>objenesis</artifactId>
   <version>1.2</version>
   <scope>test</scope>
</dependency>

person Nathan Reese    schedule 16.08.2010    source источник


Ответы (3)


Причина этого исключения в том, что Thread#isAlive() является методом final, но EasyMock не поддерживает имитацию конечных методов. Таким образом, вызов этого метода, который появляется внутри EasyMock.expect(...), не рассматривается как «вызов макета».

Чтобы издеваться над окончательными методами, вам понадобится другой инструмент для имитации, например JMockit (который я разрабатываю):

public void testMockingFinalMethod(@Mocked("isAlive") Thread mock)
{
    new Expectations()
    {{
        mock.isAlive(); result = true;
    }};

    assertTrue(mock.isAlive());
}

Мокающий API на самом деле не требует, чтобы имитируемые методы указывались явно, в общем случае. Однако класс Thread сложен.

person Rogério    schedule 15.02.2011

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

EasyMock.replay(mockObject1, mockObject2, ...);

Это подготовит имитируемый объект, который будет использоваться при запуске вашего JUnit. Никаких проблем с вашими зависимостями.

Кроме того, похоже, вы не вызываете фактический метод, который вы здесь тестируете. Обычно способ написания тестового метода заключается в написании метода JUnit с использованием имитационных библиотек (таких как EasyMock и PowerMock) ТОЛЬКО при наличии внешних объектов за пределами контекста тестового метода, а затем повторное воспроизведение всех имитируемых объектов (что подготавливает макеты для замены реальных бизнес-объектов в тесте). После этого вы вызываете фактический метод, который пытаетесь протестировать, и проверяете функциональность с помощью org.junit.Assert.assertXXX() методов.

person Nagendra U M    schedule 02.09.2010

У меня было несколько вызовов EasyMock.replay(mock) в одном тестовом примере или наборе, вызывающих эту проблему, и вызов EasyMock.reset(mock) между каждым из них решил проблему.

person SlappyTheFish    schedule 03.01.2020