gpt4 book ai didi

java - 将 PowerMock 与嵌入式 Tomcat 结合使用

转载 作者:行者123 更新时间:2023-11-28 22:27:08 25 4
gpt4 key购买 nike

我正在尝试模拟一个由嵌入式 Tomcat 实例调用的静态方法。这是我的测试类:

@RunWith(PowerMockRunner.class)
@PrepareForTest(ExternalAPI.class)
@PowerMockIgnore({"javax.management.*"})
public class TestExternalAPI
{

@Before
public void setup() {
Tomcat tomcat = new Tomcat();
tomcat.setPort(8080);
tomcat.enableNaming();
tomcat.addWebapp("/app", new File("src/test/webapp").getAbsolutePath());
tomcat.start();
}

@Test
public void testAPI() {
mockStatic(ExternalAPI.class);
when(ExternalAPI.getData()).thenReturn(new Data());

//call Tomcat triggering the call to ExternalAPI.getData()
}
}

使用此配置我得到以下异常:

java.lang.NoSuchMethodException: org.apache.catalina.deploy.WebXml addServlet
at org.apache.tomcat.util.IntrospectionUtils.callMethod1(IntrospectionUtils.java:849)
at org.apache.tomcat.util.digester.SetNextRule.end(SetNextRule.java:201)
at org.apache.tomcat.util.digester.Digester.endElement(Digester.java:1060)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:609)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(XMLDocumentFragmentScannerImpl.java:1783)
...

现在我想也许我需要告诉 PowerMock 忽略 org.apache.* 包,但后来我得到了这个异常:

java.lang.ClassCastException: com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl cannot be cast to javax.xml.parsers.SAXParserFactory
at javax.xml.parsers.FactoryFinder.newInstance(FactoryFinder.java:190)
... 54 more

我也尝试过忽略所有 org.* 包,这很有效,但是 ExternalAPI.getData() 方法根本没有被模拟。我想这是因为在这种情况下 Tomcat 实例中的任何东西都没有被模拟,因为我们忽略了那些 org.apache.* 包。

为什么会出现这些异常,我应该如何配置 PowerMock?

编辑:我使用的是 Tomcat 7。如果不使用 PowerMock,测试使用嵌入式 Tomcat 实例运行良好。

最佳答案

我认为在嵌入式模式下使用 tomcat 时,您应该设置所有必需的东西,例如协议(protocol)、生命周期监听器(如果有)、servlet 类、上下文参数...

对我有用的示例代码...

    tomcat = new Tomcat();

// Trigger loading of catalina.properties
CatalinaProperties.getProperty("foo");

File appBase = new File(getTemporaryDirectory(), "webapps");
if (!appBase.exists() && !appBase.mkdir()) {
Assert.fail("Unable to create appBase for test");
}

String protocol = getProtocol();

Connector connector = new Connector(protocol);
// Listen only on localhost
connector.setAttribute("address",
InetAddress.getByName("localhost").getHostAddress());
// Use random free port
connector.setPort(0);
// Mainly set to reduce timeouts during async tests
connector.setAttribute("connectionTimeout", "3000");
tomcat.getService().addConnector(connector);
tomcat.setConnector(connector);

// Add AprLifecycleListener if we are using the Apr connector
if (protocol.contains("Apr")) {
StandardServer server = (StandardServer) tomcat.getServer();
AprLifecycleListener listener = new AprLifecycleListener();
listener.setSSLRandomSeed("/dev/urandom");
server.addLifecycleListener(listener);
connector.setAttribute("pollerThreadCount", Integer.valueOf(1));
}

File catalinaBase = getTemporaryDirectory();
tomcat.setBaseDir(catalinaBase.getAbsolutePath());
tomcat.getHost().setAppBase(appBase.getAbsolutePath());

System.setProperty("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE", "true");

Context ctx = tomcat.addContext(getContext(), appBase.getAbsolutePath());
ctx.setParentClassLoader(EmbeddedTomcatTestBase.class.getClassLoader());
//Set execution independent of current thread context classloader (compatibility with exec:java mojo)

Wrapper w = Tomcat.addServlet(ctx, "ServletName", ServletClass.class.getName());
w.setLoadOnStartup(1);
w.addMapping("/ServletURI/*");
w.addMapping("/ServletURI");
w.addInitParameter("StatusPage", "/diagnostic/status.jsp");


Wrapper w1 = Tomcat.addServlet(ctx, "statusJSP", JspServlet.class.getName());
w1.addMapping("/diagnostic/status.jsp");

Wrapper w3 = Tomcat.addServlet(ctx, "errorJSP", JspServlet.class.getName());
w3.addMapping("/diagnostic/error.jsp");


ctx.addParameter("EmbeddedMode", "true");

ctx.addApplicationListener(ServletContextListnereClass.class.getName());

ContextConfig contextConfig = new ContextConfig();
ctx.addLifecycleListener(contextConfig);

Tomcat.initWebappDefaults(ctx);
tomcat.start();


// initialize your engine / invoke any java methods of your interest here..

关于java - 将 PowerMock 与嵌入式 Tomcat 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39374863/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com