簡體   English   中英

PowerMock :: [java.lang.IllegalStateException:沒有最后一次調用可用的模擬]

[英]PowerMock:: [java.lang.IllegalStateException: no last call on a mock available]

模擬靜態方法powermock在expect()時給出異常。

@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方法,而m使用powerMock我正在使用intelliJ的想法,如何解決該異常。

您的代碼缺少注釋

@PrepareForTest(IdGenerator.class)

在我的情況下,我在我的測試類中缺少以下方法

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

一旦我添加它,我擺脫了“沒有最后一次調用可用的模擬”錯誤。

您需要在實際調用方法之前放置重播。

編輯:我認為部分問題可能是由於您的導入造成的。 盡量不要導入靜態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;
     }
}

這個問題已經存在了很長一段時間,但我會嘗試給它一個aswer來解釋我為解決這個問題所采取的措施。

首先,您必須使用這兩個注釋:

@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:

  • 導入:import 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;

我希望這個答案清楚完整

順便說一下,我將向您介紹一些有用的鏈接:

GitHub上的PowerMock靜態文檔

Mvn存儲庫PowerMock庫

見到你:D

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM