即使在添加@PrepareForTest之后,Mockito也要求为该类添加@PrepareForTest

时间:2016-06-20 14:25:29

标签: java mockito powermock

我有以下简单的代码。我有一个类(TestClass),我想测试“someMethod”。有一个外部静态方法,由我的“someMethod”调用。 我想Powermock那个静态方法给我一些虚拟对象。 我在开头有@PrepareForTest(ExternalClass.class),但是当我执行它时会出错:

类ExternalClass未准备好进行测试。 要准备此类,请将类添加到'@PrepareForTest'注释中。 如果您不使用此批注,请在类或方法级别添加批注。

请帮助我指出我使用@PrepareForTest

的方式有什么问题
@RunWith(PowerMockRunner.class)
@PrepareForTest(ExternalClass.class)
public class xyzTest {  
    @Mock
    private RestTemplate restTemplate;

    @Mock
    private TestClass testClass;

    @BeforeClass
    private void setUpBeforeClass() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testSuccessCase() {
        Boolean mockResponse = true;
        ResponseEntity<Boolean> response = new ResponseEntity<Boolean>(mockResponse, HttpStatus.OK);
        SomeClass someClass = new SomeClass("test", "1.0.0", "someUrl", "someMetaData");

        PowerMockito.mockStatic(ExternalClass.class);

        Mockito.when(restTemplate.postForEntity(any(String.class), any(String.class), eq(Boolean.class))).thenReturn(response);
        Mockito.when(ExternalClass.getSomeClass(any(String.class))).thenReturn(someClass);

        Boolean result = testClass.someMethod("test");

        Assert.isTrue(result);
        Mockito.verify(restTemplate, times(1)).postForObject(any(String.class), any(String.class), any());
    }
}

11 个答案:

答案 0 :(得分:15)

请务必将@RunWith(PowerMockRunner.class)添加到班级的顶部。

答案 1 :(得分:5)

与上一个答案一样,我的问题还在于混合来自TestNG的Test annotation而不是Junit Test。

import org.junit.Test; // works

import org.testng.annotations.Test // did not work

非常深奥的错误,我花了超过5小时的调试:(

答案 2 :(得分:5)

我遇到了同样的错误,通过添加

解决了这个问题
@Rule
public PowerMockRule rule = new PowerMockRule();

在测试类中。

答案 3 :(得分:3)

检查是否导入 org.junit.Test;包已经导入,而不是那个 api jupiter 一个。

答案 4 :(得分:2)

对于那些尝试使用Junit 5的用户,如果您使用声称与4+兼容的powermock-module-junit4测试版,那么该库仍然无法识别:

import org.junit.jupiter.api.Test;

它将抛出:

org.powermock.api.mockito.ClassNotPreparedException

在您要静态模拟的类上应用@PrepareForTest时。如果你想使用PowerMock,你必须回到Junit 4或者为你的静态方法创建一个MockWrapper。

PowerMock 2.0:Github Roadmap

答案 5 :(得分:1)

我遇到了同样的错误,但解决了它。我的问题是我包含了powermock-module-junit4但是包含了来自TestNG而不是Junit的测试注释。

答案 6 :(得分:0)

如果以上答案无效,请尝试extends PowerMockTestCase。这个技巧对我有用。

示例: public class xyzTest extends PowerMockTestCase

答案 7 :(得分:0)

我有同样的错误。我正在使用TestNG来运行测试。我必须使用以下方法来解决上述问题。

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

答案 8 :(得分:0)

毫无疑问,这里最受好评的答案是正确的,但这没有回答为什么需要 的问题;或者,例如,为什么同一件事不能通过添加@RunWith(MockitoJUnitRunner.class)而起作用。

问题是PowerMockRunner通过在后台使用工具API javassist库,这允许更改类,例如删除final或模拟static(非编译时间常数)。

在修改(插入)某个类的过程中,他们向该类添加一个名为PowerMockModified的接口。这是一个标记接口,表示发生了某种字节码检测。在代码的后面,他们只是通过以下方法检查您在@PrepareForTest中使用的类是否确实以某种方式进行了检测:

    private boolean isModifiedByPowerMock() {
        return PowerMockModified.class.isAssignableFrom(this.type);
    }

事实证明,PowerMockRunner做某些工具,而MockitoJUnitRunner做不到;因此,您得到的错误。

答案 9 :(得分:0)

确保您使用的是 powermock2。我在使用 powermock 时遇到了这个问题。 使用

import org.powermock2.api.mockito.PowerMockito;

答案 10 :(得分:-1)

对于testNG,有以下两种选择:

  1. 使用ObjectFactory如下:
    @ObjectFactory
    public IObjectFactory getObjectFactory() {
        return new PowerMockObjectFactory();
    }
  1. 扩展extends org.powermock.modules.testng.PowerMockTestCase的测试类