2017-10-07 46 views
0

我有以下罐:PowerMockito ClassNotPreparedException

javax.servlet-api-3.1.9.jar 
junit-4.10.jar 
mockito-all-1.10.19.jar 
mockito-core-1.10.19.jar 
powermock-api-mockito-1.6.5.jar 
powermock-api-mockito-common-1.6.5.jar 
powermock-api-support-1.6.5.jar 
powermock-core-1.6.5.jar 
powermock-module-junit4-1.6.5.jar 
powermock-reflect-1.6.5.jar 

我想测试此方法称为createPanel这是一种称为Controller类中:

public static void createPanel(HttpServletRequest req, HttpServletResponse res, HttpSession hs) throws IOException 
{ 
    PanelManager.createPanel(req, res, hs); 
} 

ControllerTest类(junit的测试仪),我有这个:

import static org.mockito.Mockito.verify; 
import static org.mockito.Mockito.when; 
import java.io.IOException; 
import java.io.PrintWriter; 
import javax.servlet.ServletException; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import javax.servlet.http.HttpSession; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.mockito.Mockito; 
import org.mockito.runners.MockitoJUnitRunner; 
import org.powermock.api.mockito.PowerMockito; 
import org.powermock.core.classloader.annotations.PrepareForTest; 
import org.powermock.modules.junit4.PowerMockRunner; 
import ApplicationLogic.Controller; 
import ApplicationLogic.PanelManager; 
import ApplicationLogic.RegistrationManager; 
import ApplicationLogic.SessionManager; 

@PrepareForTest(PanelManager.class) 
@RunWith(MockitoJUnitRunner.class) 

public class ControllerTest { 

    Controller controller = Mockito.mock(Controller.class); 

    SessionManager sessionManager = Mockito.mock(SessionManager.class); 

    RegistrationManager registrationManager = Mockito.mock(RegistrationManager.class); 
     . 
     . 
     . 
     . 

    @Test 

public void testcreatePanel() throws ServletException, IOException{ 

    HttpServletRequest req = Mockito.mock(HttpServletRequest.class); 
    HttpServletResponse res = Mockito.mock(HttpServletResponse.class); 
    HttpSession hs = Mockito.mock(HttpSession.class); 


    //PowerMockito.mock(SessionManager.class); 

    PrintWriter writer = new PrintWriter("somefile.txt"); 
    when(res.getWriter()).thenReturn(writer); 

    PowerMockito.mockStatic(Controller.class); 

    PowerMockito.doCallRealMethod().when(controller).createPanel(req, res, hs); 

所有的测试s在控制器类中的其他方法运行良好。为什么它是在PowerMockito.doCallRealMethod()导致此错误:

org.powermock.api.mockito.ClassNotPreparedException: 
The class ApplicationLogic.Controller 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. 

    at org.powermock.api.mockito.expectation.reporter.MockitoPowerMockReporter.classNotPrepared(MockitoPowerMockReporter.java:31) 
    at org.powermock.api.mockito.internal.mockcreation.MockTypeValidatorFactory$DefaultMockTypeValidator.validate(MockTypeValidatorFactory.java:38) 
    at org.powermock.api.mockito.internal.mockcreation.AbstractMockCreator.validateType(AbstractMockCreator.java:18) 
    at org.powermock.api.mockito.internal.mockcreation.MockCreator.createMock(MockCreator.java:57) 
    at org.powermock.api.mockito.internal.mockcreation.MockCreator.mock(MockCreator.java:47) 
    at org.powermock.api.mockito.PowerMockito.mockStatic(PowerMockito.java:71) 
    at JUnitTest.ControllerTest.testcreatePanel(ControllerTest.java:253) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42) 
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300) 
    at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37) 
    at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 

回答

1

您必须使用PowerMockRunner代替MockitoJUnitRuner

这个例子解决了ClassNotPreparedException

@RunWith(PowerMockRunner.class) 
@PrepareForTest({PanelManager.class}) 
public class ControllerTest { 

    Controller controller = Mockito.mock(Controller.class); 

    @Test 
    public void testcreatePanel() throws Exception { 
     HttpServletRequest req = Mockito.mock(HttpServletRequest.class); 
     HttpServletResponse res = Mockito.mock(HttpServletResponse.class); 
     HttpSession hs = Mockito.mock(HttpSession.class); 

     PrintWriter writer = new PrintWriter("somefile.txt"); 
     Mockito.when(res.getWriter()).thenReturn(writer); 

     PowerMockito.mockStatic(PanelManager.class); 
     PowerMockito.doCallRealMethod().when(controller).createPanel(req, res, hs); 
    } 
} 

但是,它看起来像有可能仍然是即使有些问题;你正在嘲笑控制器,然后通过调用doCallRealMethod()就可以将其视为部分模拟。也许有一个真正的原因(也许因此会通过展示更多的代码来显示),但如果你没有为一个真正的理由,那么你可以删除此行:

Controller controller = Mockito.mock(Controller.class); 

而且替换此行...

PowerMockito.doCallRealMethod().when(controller).createPanel(req, res, hs); 

与此:

Controller.createPanel(req, res, hs); 

这则允许你嘲笑的PanelManager行为和测试实际行为Controller回应PanelManager的嘲弄行为。

+0

谢谢我刚刚看到您的回复。那么为什么会这样工作?因为我没有使用'doCallRealMethod()',它没有关系? – Lazaro

+0

@拉齐罗你问“为什么会这样?”我不确定那个“那”是指什么。在我回答这个部分:“使用PowerMockRunner而不是MockitoJUnitRuner”修复了ClassNotPreparedException。我的答案中的其他建议避免了完全使用“PowerMockito.doCallRealMethod()”,而是使用真正的Controller实例。 – glytching