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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37925034/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 19:48:47  来源:igfitidea点击:

Mockito asks to add @PrepareForTest for the class even after adding @PrepareForTest

javamockitopowermock

提问by ViV

I have the following simple code. I have a class (TestClass) and I want to test "someMethod". There is an external static method which is called by my "someMethod". I want to Powermock that static method to return me some dummy object. I have the @PrepareForTest(ExternalClass.class) in the begining, but when I execute it gives the error:

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

The class ExternalClass not prepared for test. To prepare this class, add class to the '@PrepareForTest'annotation. In case if you don't use this annotation, add the annotation on class or method level.

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

Please help me to point out what is wrong with the way I have used @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());
    }
}

采纳答案by wild_nothing

Make sure you add @RunWith(PowerMockRunner.class)to the top of your class as well.

确保你@RunWith(PowerMockRunner.class)也在班级中名列前茅。

::edit:: two years later...

::edit:: 两年后...

Don't ever use PowerMockito, you shouldn't need to.

永远不要使用 PowerMockito,你不应该需要。

If you do need to, you have most likely broken the SOLID principles and your design is wrong.

如果确实需要,您很可能违反了 SOLID 原则并且您的设计是错误的。

Fix your design instead.

修复您的设计。

回答by Dan

I had the same error but resolved it. My problem was that I included powermock-module-junit4but included my test annotation from TestNG instead of Junit.

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

回答by user2121316

As with the last answer, my problem was also mixing the Test annotation from TestNG instead of Junit Test.

与上一个答案一样,我的问题也是混合来自 TestNG 的 Test 注释而不是 Junit Test。

import org.junit.Test; // works

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

Very abstruse error and I spent more than 5 hrs debugging :(

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

回答by Felicia Agatha

I had the same error, resolved this by adding

我有同样的错误,通过添加解决了这个问题

@Rule
public PowerMockRule rule = new PowerMockRule();

inside the test class.

在测试类里面。

回答by Aaron Tobias

For those trying to get this working with Junit 5, If your using the powermock-module-junit4beta release which claims to be compatible with 4+, the library will still not recognize:

对于那些试图与 Junit 5 一起使用的人,如果您使用powermock-module-junit4声称与 4+ 兼容的beta 版本,该库仍将无法识别:

import org.junit.jupiter.api.Test;

and it will throw a:

它会抛出一个:

org.powermock.api.mockito.ClassNotPreparedException

when @PrepareForTestis applied on the class you want to static mock. If you want to use PowerMock, you will have to go back to Junit 4 or create a MockWrapper for your static method at this time.

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

PowerMock 2.0: Github Roadmap

PowerMock 2.0:Github 路线图

回答by Akshay Thorve

If above answers don't work try extends PowerMockTestCase. This trick worked for me.

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

Example: public class xyzTest extends PowerMockTestCase

例子: public class xyzTest extends PowerMockTestCase

回答by Will_Panda

I had the same error. I was using TestNG to run the tests. I had to use the following method to fix the above issue.

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

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

回答by Eugene

While the top-rated answer here is correct without a doubt, this does not answer the question of whyis that needed; or, for example, why the same thing would not work with adding @RunWith(MockitoJUnitRunner.class).

虽然这里评分最高的答案毫无疑问是正确的,但这并没有回答为什么需要这样的问题;或者,例如,为什么添加@RunWith(MockitoJUnitRunner.class).

The thing is PowerMockRunneruses instrumentation API under the hood, via javassistlibrary, this allows to alter the classes, like remove finalor mock static(non-compile time constants).

事情是PowerMockRunner在引擎盖下使用检测 API,通过 javassist库,这允许更改类,如删除final或模拟static(非编译时常量)。

In the process of modifying (instrumenting) a certain class, they add an interface to that, called PowerMockModified. It is a marker interface that denotes that a certain byte-code instrumentation took place. Later in the code, they simply check if the class that you use in @PrepareForTestwas actually instrumented in some way or not, via such a method:

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

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

In turns out that PowerMockRunnerdoessome instrumentation, while MockitoJUnitRunnerdoes not; thus the error you get.

事实证明,PowerMockRunner它做了一些检测,而MockitoJUnitRunner没有;因此你得到的错误。