为什么我必须扩展 PowerMockTestCase?

Why do I have to extend PowerMockTestCase?

当我不从 PowerMockTestCase 扩展时,下面的测试抛出 java.lang.IllegalStateException: no last call on a mock available

我从 PowerMockTestCase 扩展后,错误就消失了。为什么会发生这种情况?

import static org.junit.Assert.assertEquals;

import org.easymock.EasyMock;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockTestCase;

@PrepareForTest({ IdGenerator.class, ServiceRegistartor.class })
public class SnippetTest extends PowerMockTestCase{

    @org.testng.annotations.Test
    public void testRegisterService() throws Exception {
        long expectedId = 42;

        // We create a new instance of test class under test as usually.
        ServiceRegistartor tested = new ServiceRegistartor();

        // This is the way to tell PowerMock to mock all static methods of a
        // given class
        PowerMock.mockStatic(IdGenerator.class);

        /*
         * The static method call to IdGenerator.generateNewId() expectation.
         * This is why we need PowerMock.
         */
        EasyMock.expect(IdGenerator.generateNewId()).andReturn(expectedId).once();

        // Note how we replay the class, not the instance!
        PowerMock.replay(IdGenerator.class);

        long actualId = tested.registerService(new Object());

        // Note how we verify the class, not the instance!
        PowerMock.verify(IdGenerator.class);

        // Assert that the ID is correct
        assertEquals(expectedId, actualId);
    }

}

在使用 PowerMock 进行静态模拟时,有一个 class 级别的工具可以让您的模拟工作正常进行。 PowerMockTestCase class 有一个代码(方法 beforePowerMockTestClass())可以将你的常规 class 加载器切换到 powermock class 加载器,它可以协调模拟注入。因此,您需要扩展此 class 才能使静态模拟正常工作。

您需要配置 PowerMock class-加载程序,以便可以拦截静态 classes(使用 @PrepareForTest 注释定义)。

您不必从 PowerMockTestCase 进行扩展。对于大多数情况,您还可以使用 PowerMockObjectFactory 来配置 TestNG:

@PrepareForTest({ IdGenerator.class, ServiceRegistartor.class })
public class SnippetTest {

   @ObjectFactory
   public IObjectFactory objectFactory() {
      return new PowerMockObjectFactory();
   }

   @org.testng.annotations.Test
   public void testRegisterService() throws Exception {
      ...
   }
}