5

我在集成测试中使用 ShrinkWrap 启动 Jetty 服务器。

问题:

当我启动我的测试码头服务器而不是制作我的控制器模型时 - 模型不起作用!我建议原因是不同的类加载器:JMockit - AppClassLoader,Jetty - WebAppClassLoader。

问题:

如何使嘲笑工作正常?

PS 我已经用谷歌搜索了-javaagent:jmockit.jar选项可能会有所帮助。但事实并非如此。基于1.7 jdk的maven项目有必要吗?

添加:

我写了演示来说明我的问题。您可以通过参考找到它。

关于我的演示:

除了十个代码之外,它与那些项目相同。我只添加了 JMockit 和一个模拟来说明问题。

您应该看到JettyDeploymentIntegrationUnitTestCase.requestWebapp方法:在这些方法中,我们制作了不起作用的模拟。

您可以检查 Jetty & JMockit 通过兄弟类加载器加载类,因此 JMockit 根本看不到 Jetty 的类

URLClassLoader
|
|-Launcher$AppClassLoader
|-WebAppClassLoader
4

1 回答 1

3

示例项目中的 JUnit 测试正在尝试模拟ForwardingServlet该类。但是,在这个带有嵌入式 Jetty Web 服务器的场景中,实际上有这个类的两个实例,它们都加载到同一个 JVM 中,但通过不同的类加载器加载。

类的第一个实例由常规类加载器加载,通过该类加载器从启动 JUnit 测试运行器 ( AppClassLoader) 的线程中加载类。因此,当ForwardingServlet出现在测试代码中时,它就是这个类加载器中定义的那个。这是给 JMockit 模拟的类,这正是发生的事情。

但是随后,使用Jetty的. JMockit 从未见过此类。ForwardingServletWebAppClassLoader

这个问题有两种可能的解决方案:

  1. 以某种方式获取加载的类对象WebAppClassLoader,然后通过调用MockUp(Class)构造函数来模拟它。

  2. 配置 Jetty 服务器,使其不对Web 应用程序中的类使用自定义类加载器。

第二种解决方案是最简单的,只需在ContextHandler从对象创建的WebArchive对象上添加以下调用,然后将处理程序设置为 JettyServer对象即可:

handler.setClassLoader(ClassLoader.getSystemClassLoader());

我对此进行了测试,它按预期工作,该@Mock doGet(...)方法被执行,而不是真正的ForwardingServlet.

于 2013-09-24T16:11:33.543 回答