JMockit + Jetty进行功能测试

VB_*_*VB_ 5 jetty jmockit functional-testing

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

问题:

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

题:

如何使模拟工作正常?

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

加成:

我写了演示来解释我的问题.您可以通过参考找到它.

关于我的演示:

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

您应该看到JettyDeploymentIntegrationUnitTestCase.requestWebapp方法:在那些方法中,我们使模拟不起作用.

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

URLClassLoader
|
|-Launcher$AppClassLoader
|-WebAppClassLoader
Run Code Online (Sandbox Code Playgroud)

Rog*_*rio 3

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

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

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

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

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

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

第二种解决方案是最简单的,只需在将处理程序设置到 Jetty 对象之前,在ContextHandler从该对象创建的对象上添加以下调用即可完成:WebArchiveServer

handler.setClassLoader(ClassLoader.getSystemClassLoader());
Run Code Online (Sandbox Code Playgroud)

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