即使在添加 @PrepareForTest 之后,Mockito 仍要求为 class 添加 @PrepareForTest
Mockito asks to add @PrepareForTest for the class even after adding @PrepareForTest
我有以下简单的代码。我有一个 class (TestClass),我想测试 "someMethod"。我的 "someMethod" 调用了一个外部静态方法。
我想将那个静态方法 Powermock 到 return 我一些虚拟对象。
一开始我有 @PrepareForTest(ExternalClass.class) ,但是当我执行它时出现错误:
classExternalClass 没有准备测试。
要准备此 class,请将 class 添加到 '@PrepareForTest'
注释中。
如果您不使用此注释,请在 class 或方法级别添加注释。
请帮我指出我使用的方式有什么问题@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());
}
}
我遇到了同样的错误,但已解决。我的问题是我包含了 powermock-module-junit4
但包含了来自 TestNG 而不是 Junit 的测试注释。
确保将 @RunWith(PowerMockRunner.class)
也添加到 class 的顶部。
::edit:: 两年后...
永远不要使用 PowerMockito,你不需要。
如果您确实需要,您很可能违反了 SOLID 原则并且您的设计是错误的。
改正您的设计。
与上一个答案一样,我的问题还在于混合了来自 TestNG 而不是 Junit Test 的测试注释。
import org.junit.Test; // works
import org.testng.annotations.Test // did not work
非常深奥的错误,我花了 5 个多小时调试 :(
我有同样的错误,通过添加
解决了这个问题
@Rule
public PowerMockRule rule = new PowerMockRule();
内测class.
对于那些试图让它与 Junit 5 一起工作的人,如果您使用的是声称与 4+ 兼容的 powermock-module-junit4
测试版,该库仍然无法识别:
import org.junit.jupiter.api.Test;
它会抛出一个:
org.powermock.api.mockito.ClassNotPreparedException
当 @PrepareForTest
应用于 class 时,您想要静态模拟。如果你想使用 PowerMock,此时你将不得不回到 Junit 4 或为你的静态方法创建一个 MockWrapper。
PowerMock 2.0:Github Roadmap
如果以上答案无效,请尝试 extends PowerMockTestCase
。这个技巧对我有用。
示例:
public class xyzTest extends PowerMockTestCase
我有同样的错误。我正在使用 TestNG 运行 进行测试。我不得不使用以下方法来解决上述问题。
@ObjectFactory
public IObjectFactory getObjectFactory() {
return new PowerMockObjectFactory();
}
虽然这里评分最高的答案毫无疑问是正确的,但这并没有回答 为什么需要 的问题;或者,例如,为什么添加 @RunWith(MockitoJUnitRunner.class)
.
同样的事情不起作用
事情是 PowerMockRunner
在幕后使用仪器 API,通过
javassist 库,这允许更改 classes,例如删除 final
或模拟 static
(非编译时间常数)。
在修改(检测)某个 class 的过程中,他们为其添加了一个接口,称为 PowerMockModified
。它是一个标记接口,表示发生了某个字节码检测。在代码的后面,他们只是通过这样的方法检查您在 @PrepareForTest
中使用的 class 是否实际上以某种方式进行了检测:
private boolean isModifiedByPowerMock() {
return PowerMockModified.class.isAssignableFrom(this.type);
}
事实证明 PowerMockRunner
做 一些检测,而 MockitoJUnitRunner
没有;因此你得到的错误。
对于 testNG,有 2 个选项如下:
- 使用 ObjectFactory 如下:
@ObjectFactory
public IObjectFactory getObjectFactory() {
return new PowerMockObjectFactory();
}
- 测试 class 扩展
extends org.powermock.modules.testng.PowerMockTestCase
检查是否导入org.junit.Test;包已导入,而不是 api jupiter one。
确保您使用的是 powermock2。我在使用 powermock 时遇到了这个问题。
使用
import org.powermock2.api.mockito.PowerMockito;
我的 gradle 使用的是 Junit 5。
test {
useJUnitPlatform()
}
我能够调试它。通过在 PowerMockRunner 方法中设置断点。
它没有被调用。此外,PowerMockito 不支持 JUnit 5。
看起来 JUnit5 在没有 @ExtendWith 的情况下运行。
我有以下简单的代码。我有一个 class (TestClass),我想测试 "someMethod"。我的 "someMethod" 调用了一个外部静态方法。 我想将那个静态方法 Powermock 到 return 我一些虚拟对象。 一开始我有 @PrepareForTest(ExternalClass.class) ,但是当我执行它时出现错误:
classExternalClass 没有准备测试。
要准备此 class,请将 class 添加到 '@PrepareForTest'
注释中。
如果您不使用此注释,请在 class 或方法级别添加注释。
请帮我指出我使用的方式有什么问题@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());
}
}
我遇到了同样的错误,但已解决。我的问题是我包含了 powermock-module-junit4
但包含了来自 TestNG 而不是 Junit 的测试注释。
确保将 @RunWith(PowerMockRunner.class)
也添加到 class 的顶部。
::edit:: 两年后...
永远不要使用 PowerMockito,你不需要。
如果您确实需要,您很可能违反了 SOLID 原则并且您的设计是错误的。
改正您的设计。
与上一个答案一样,我的问题还在于混合了来自 TestNG 而不是 Junit Test 的测试注释。
import org.junit.Test; // works
import org.testng.annotations.Test // did not work
非常深奥的错误,我花了 5 个多小时调试 :(
我有同样的错误,通过添加
解决了这个问题@Rule
public PowerMockRule rule = new PowerMockRule();
内测class.
对于那些试图让它与 Junit 5 一起工作的人,如果您使用的是声称与 4+ 兼容的 powermock-module-junit4
测试版,该库仍然无法识别:
import org.junit.jupiter.api.Test;
它会抛出一个:
org.powermock.api.mockito.ClassNotPreparedException
当 @PrepareForTest
应用于 class 时,您想要静态模拟。如果你想使用 PowerMock,此时你将不得不回到 Junit 4 或为你的静态方法创建一个 MockWrapper。
PowerMock 2.0:Github Roadmap
如果以上答案无效,请尝试 extends PowerMockTestCase
。这个技巧对我有用。
示例:
public class xyzTest extends PowerMockTestCase
我有同样的错误。我正在使用 TestNG 运行 进行测试。我不得不使用以下方法来解决上述问题。
@ObjectFactory
public IObjectFactory getObjectFactory() {
return new PowerMockObjectFactory();
}
虽然这里评分最高的答案毫无疑问是正确的,但这并没有回答 为什么需要 的问题;或者,例如,为什么添加 @RunWith(MockitoJUnitRunner.class)
.
事情是 PowerMockRunner
在幕后使用仪器 API,通过
javassist 库,这允许更改 classes,例如删除 final
或模拟 static
(非编译时间常数)。
在修改(检测)某个 class 的过程中,他们为其添加了一个接口,称为 PowerMockModified
。它是一个标记接口,表示发生了某个字节码检测。在代码的后面,他们只是通过这样的方法检查您在 @PrepareForTest
中使用的 class 是否实际上以某种方式进行了检测:
private boolean isModifiedByPowerMock() {
return PowerMockModified.class.isAssignableFrom(this.type);
}
事实证明 PowerMockRunner
做 一些检测,而 MockitoJUnitRunner
没有;因此你得到的错误。
对于 testNG,有 2 个选项如下:
- 使用 ObjectFactory 如下:
@ObjectFactory
public IObjectFactory getObjectFactory() {
return new PowerMockObjectFactory();
}
- 测试 class 扩展
extends org.powermock.modules.testng.PowerMockTestCase
检查是否导入org.junit.Test;包已导入,而不是 api jupiter one。
确保您使用的是 powermock2。我在使用 powermock 时遇到了这个问题。 使用
import org.powermock2.api.mockito.PowerMockito;
我的 gradle 使用的是 Junit 5。
test {
useJUnitPlatform()
}
我能够调试它。通过在 PowerMockRunner 方法中设置断点。 它没有被调用。此外,PowerMockito 不支持 JUnit 5。
看起来 JUnit5 在没有 @ExtendWith 的情况下运行。