2013-06-25 5 views
2

Чтобы издеваться над статическим методом powermock, дающим исключение while expect().PowerMock :: [java.lang.IllegalStateException: no last call on mock available]

@Test 
public void testRegistrarService() 
{ 
    mockStatic(IdGenerator.class); 
    expect(IdGenerator.generateNewId()).andReturn(42L); 
    long actualId=serTestObj.registerService(); 
    replay(IdGenerator.class); 
    verify(IdGenerator.class); 
    assertEquals(42L,actualId); 
} 


public class ServiceRegistrator 
{ 
public long registerService() 
{ 
    long id = IdGenerator.generateNewId(); 
    return id; 
} 
} 

public class IdGenerator 
{ 
    public static long generateNewId() 
    { 
    return System.currentTimeMillis(); 
    } 
} 

Исключение:

java.lang.IllegalStateException: no last call on a mock available 
at org.easymock.EasyMock.getControlForLastCall(EasyMock.java:521) 
at org.easymock.EasyMock.expect(EasyMock.java:499) 
at home.powermock.testServiceRegistrator.testRegistrarService(testServiceRegistrator.java:51) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at com.intellij.rt.execution.junit2.JUnitStarter.main(JUnitStarter.java:31) 

как издеваются staic метод, в то время как м при использовании powerMock я использую IntelliJ идея, как решить это исключение.

+0

Является 'IdGenerator.generateNewId()' 'final' метод? Если это так, http://stackoverflow.com/questions/3494969/easymock-3-0-mocking-class-throws-java-lang-illegalstateexception-no-last-call является дубликатом. Кроме того, вы, возможно, пропустили вызов 'EasyMock.replay'. –

+0

Я вызываю метод повтора здесь, как replay (IdGenerator.class); но он был пропущен здесь. – kin

+0

IdGenerator.generateNewId() не является окончательным методом. Только статический метод. – kin

ответ

5

Ваш код отсутствует аннотацию

@PrepareForTest(IdGenerator.class) 
+0

@RunWith (PowerMockRunner.class) @PrepareForTest ({testServiceRegistrator.class, IdGenerator.class} я уже добавлен как аннотацию перед классом, в котором метод испытаний присутствует. – kin

+0

удалить testServiceRegistrator.class из списка – JoseK

+0

удалены. .. все то же исключение .. :( сейчас у меня есть @PrepareForTest (IdGenerator.class) .. Я думаю, что основная причина в методе «ожидать()». что-то здесь готовит здесь. , но не может его решить? – kin

3

Вы должны поместить повторы до фактического вызова метода.

EDIT: Я думаю, что часть проблемы может быть вызвана из-за вашего импорта. Старайтесь не импортировать статические powermock и статические easymock (я обнаружил, что я часто путаю себя и забываю, какой из них мне нужно перезвонить).

Используйте следующий код. Если он работает неправильно, это может быть из-за проблемы с конкретной версией PowerMock/EasyMock/Junit, которые у вас есть.

TestClass:

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.powermock.api.easymock.PowerMock; 
import org.powermock.core.classloader.annotations.PrepareForTest; 
import org.powermock.modules.junit4.PowerMockRunner; 

import static org.easymock.EasyMock.*; 

import static org.junit.Assert.*; 
@RunWith(PowerMockRunner.class) 
@PrepareForTest(IdGenerator.class) 
public class TestClass { 

@Test 
public void testRegistrarService() 
{ 
    ServiceRegistrator serTestObj = new ServiceRegistrator(); 

    PowerMock.mockStatic(IdGenerator.class); 
    expect(IdGenerator.generateNewId()).andReturn(42L); 
    PowerMock.replay(IdGenerator.class); 
    long actualId=serTestObj.registerService(); 
    PowerMock.verify(IdGenerator.class); 
    assertEquals(42L,actualId); 
} 
} 

IdGenerator:

public class IdGenerator { 
    public static long generateNewId() 
     { 
     return System.currentTimeMillis(); 
     } 
} 

ServiceRegistrator:

public class ServiceRegistrator { 
    public long registerService() 
    { 
     long id = IdGenerator.generateNewId(); 
     return id; 
    } 
} 
+0

HardcoreBro Я попробовал ваш подход но все же одно и то же исключение ... пока не решено ... :( – kin

+0

См. пересмотренный пост. Я добавил исходный код. Я думаю, что ваша проблема может быть связана с тем, как вы импортировали свой код ...Попробуйте изменить свой импорт в соответствии с указанным выше кодом и дайте мне знать, как это происходит. – HardcoreBro

+0

все еще не работает. Такое же исключение приходит .... этот код работает на вашей среде ????? Если это так, то проблема с банкой ... то, пожалуйста, дайте мне знать, какой jar вы используете для EasyMock/PowerMock/JUnit .... – kin

4

В моем случае я пропускал следующий метод в моем тестовом классе

@ObjectFactory 
    /** 
    * Configure TestNG to use the PowerMock object factory. 
    */ 
    public IObjectFactory getObjectFactory() { 
     return new org.powermock.modules.testng.PowerMockObjectFactory(); 
    } 

Как только я добавил его, я избавился от ошибки «no last call on mocking available».

+0

В моем случае он избавился от исходного сообщения об ошибке и заменил его с «Несогласованными рамками штабеля в целевом объекте 49» ... Мне бы хотелось услышать немного больше о том, как добавить IObjectFactory. – Chris

+0

Я использую testng, а не junit и добавил RunWith. Я взял это и добавив, что ObjectFactory, похоже, у меня на моем пути. У меня есть некоторое понимание здесь: https://github.com/jayway/powermock/wiki/TestNG_usage – Chris

1

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

Прежде всего, вы должны использовать эти две аннотации:

@RunWith (PowerMockRunner.class)

Это аннотация пусть текущий класс теста знать, что использовать для выполнения своих тестов, это полезно, потому что мы можем использовать PowerMockRunner вместо JUnitRunner

@PrepareForTest (IdGenerator.class)

Это примечание используется для подготовки класса «IdGenerator», которые будут использоваться в тесте, подготовьте означает, что мы будем в состоянии издеваться статические методы, как мы делаем для открытых методов

После Добавив эти две аннотации мы должны быть уверены, что мы используем правильные пакеты, предоставляемые PowerMock:

1) PowerMock:

  • Импорт : import org.powermock.api.easymock.PowerMock;
  • Использование: Мы будем использовать PowerMock издеваться (и не только) наш статический метод с помощью следующей строки кода

    PowerMock.mockStatic (IdGenerator.class);

2) EasyMock:

  • Импорт: импорт org.easymock.EasyMock;
  • Использование: Мы будем использовать EasyMock подделать наш объект должен быть возвращен наш статический метод:.

    EasyMock.expect (IdGenerator.generateNewId()) andReturn (42L);

Это было два примера на то, что используются PowerMock и EasyMock, и здесь я попытаюсь объяснить код и что он делает:

mockStatic(IdGenerator.class); 
//We mock our IdGenerator class which have the static object 

expect(IdGenerator.generateNewId()).andReturn(42L); 
//We fake our method return object, when we'll call generateNewId() 
//method it will return 42L 
//With expecting we "record" our this method and we prepare it to be  
//changed (it will return our decided value) 

replay(IdGenerator.class); 
//We go to perform our methods "registered" with the expect method 
//inside the IdGenerator class, in this case with replay we just apply 
//the changes of the expect to the method generateNewId() 

long actualId = serTestObj.registerService(); 
//We create our object (which inside have a non static method that 
//use generateNewId() static method) 

verify(IdGenerator.class); 
//We verify that the our faked method have been called 

assertEquals(42L,actualId); 
//We see if the two values are matching 

Обратите внимание, потому что переигровка должна быть использована перед вами создайте новый объект (actualId в этом примере), который вызовет статические поддельные методы.

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

PowerMockito.mockStatic(className.class); 
//from import org.powermock.api.mockito.PowerMockito; 

Вместо

PowerMock.mockStatic(className.class); 
//from import org.powermock.api.easymock.PowerMock; 

Я надеюсь, что этот ответ ясно и полно

Кстати, я приведу вам некоторые полезные ссылки:

PowerMock Static Documentation on GitHub

Mvn Repository PowerMock Libraries

Увидимся: D