Java Mockito要求为类添加@PrepareForTest,即使在添加@PrepareForTest之后也是如此
我有以下简单的代码。我有一个类(TestClass),我想测试“someMethod”。我的“someMethod”调用了一个外部静态方法。 我想要Powermock这个静态方法来返回一些虚拟对象。 我在开头有@PrepareForTest(ExternalClass.class),但当我执行它时会出现错误: 类ExternalClass未准备好进行测试。 要准备此类,请将类添加到Java Mockito要求为类添加@PrepareForTest,即使在添加@PrepareForTest之后也是如此,java,mockito,powermock,Java,Mockito,Powermock,我有以下简单的代码。我有一个类(TestClass),我想测试“someMethod”。我的“someMethod”调用了一个外部静态方法。 我想要Powermock这个静态方法来返回一些虚拟对象。 我在开头有@PrepareForTest(ExternalClass.class),但当我执行它时会出现错误: 类ExternalClass未准备好进行测试。 要准备此类,请将类添加到“@PrepareForTest”注释中。 如果不使用此注释,请在类或方法级别添加注释 请帮我指出我使用@Prepa
“@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());
}
}
@RunWith(PowerMockRunner.class)
@PrepareForTest(ExternalClass.class)
公共类xyzTest{
@嘲弄
私有RestTemplate RestTemplate;
@嘲弄
私有测试类;
@课前
私有void setupforeclass(){
initMocks(this);
}
@试验
public void testSuccessCase(){
布尔mockResponse=true;
ResponseEntity response=新的ResponseEntity(mockResponse,HttpStatus.OK);
SomeClass SomeClass=新的SomeClass(“测试”、“1.0.0”、“someUrl”、“someMetaData”);
mockStatic(ExternalClass.class);
Mockito.when(restemplate.postForEntity(any(String.class)、any(String.class)、eq(Boolean.class)),然后返回(response);
Mockito.when(ExternalClass.getSomeClass(any(String.class))).thenReturn(someClass);
布尔结果=testClass.someMethod(“测试”);
断言(结果);
验证(restTemplate,times(1)).postForObject(any(String.class)、any(String.class)、any());
}
}
我遇到了相同的错误,但解决了它。我的问题是,我包含了powermock-module-junit4
,但包含了来自TestNG的测试注释,而不是Junit 确保将@RunWith(PowerMockRunner.class)
添加到类的顶部
::编辑::两年后…
永远不要使用PowerMockito,你不需要这样做
如果你真的需要,你很可能已经打破了坚实的原则,你的设计是错误的
改为修复您的设计。与上一个答案一样,我的问题还在于混合了来自TestNG的测试注释,而不是Junit测试
import org.junit.Test; // works
import org.testng.annotations.Test // did not work
非常深奥的错误,我花了5个多小时调试:(我也有同样的错误,通过添加
@Rule
public PowerMockRule rule = new PowerMockRule();
在测试类内部。对于那些试图在Junit 5中实现此功能的人,如果您使用声称与4+兼容的
powermock-module-junit4
beta版,库仍然无法识别:
import org.junit.jupiter.api.Test;
它将抛出一个:
org.powermock.api.mockito.ClassNotPreparedException
当@PrepareForTest
应用于要进行静态模拟的类时。如果要使用PowerMock,此时必须返回Junit 4或为静态方法创建MockWrapper
PowerMock 2.0:如果上述答案不起作用,请尝试
扩展PowerMock TestCase
。这个技巧对我很有效
例如:
公共类xyzTest扩展了PowerMockTestCase
我遇到了相同的错误。我使用TestNG运行测试。我必须使用以下方法修复上述问题
@ObjectFactory
public IObjectFactory getObjectFactory() {
return new PowerMockObjectFactory();
}
尽管这里排名靠前的答案毫无疑问是正确的,但这并不能回答为什么需要这样做的问题;或者,例如,为什么添加
@RunWith(MockitoJUnitRunner.class)
时同样的事情不起作用
问题是,PowerMockRunner
通过
库中,这允许更改类,如removefinal
或mockstatic
(非编译时常量)
在修改(仪表化)过程中对于某个类,他们添加了一个接口,称为PowerMockModified
。它是一个标记接口,表示发生了某个字节码插装。在代码的后面,他们只需检查您在@PrepareForTest
中使用的类是否通过以下方法以某种方式插装:
private boolean isModifiedByPowerMock() {
return PowerMockModified.class.isAssignableFrom(this.type);
}
事实证明,
PowerMockRunner
执行了一些指令插入,而MockitoJUnitRunner
没有;因此您会得到错误。对于testNG,有两个选项,如下所示:
@ObjectFactory
公共IObjectFactory getObjectFactory(){
返回新的PowerMockObjectFactory();
}
扩展org.powermock.modules.testng.PowerMockTestCase
检查import org.junit.Test;包是否已导入而不是api jupiter one。确保您使用的是powermock2。我在使用powermock时遇到此问题。 使用
您在JUnit4上的桌面JVM中运行这个类,对吗?ExternalClass不是Java系统类?是的,我在桌面JVM(Oracle,1.8)上运行它。ExternalClass是一个自定义Java类(不是Java系统类:即Java**),我看到您在使用
MockitoAnnotations.initMocks(…)
以及使用Powermock JUnit Runner。这是不必要的。Powermock Runner将设置您的Mock。我不知道这是否有助于您的情况,因为我遇到了同样的问题,并且我没有额外调用来初始化Mock。对我来说,它工作得很好。您使用的Mockito和Powermockito版本是什么?您应该ld一定要按照@Dan的建议检查导入。但是,由于将@BeforeClass
注释应用于非静态方法setUpBeforeClass
,并将其委托给springrunner,以便您可以将其与spring boot集成;@PowerMockRunnerDelegate(springrunner.class)这个答案是没有帮助的。即使大多数时候你不应该模仿静态方法,也要将静态方法转换为
import org.powermock2.api.mockito.PowerMockito;