JMockit + Jetty进行功能测试

时间:2013-09-19 13:55:46

标签: jetty functional-testing jmockit

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

问题:

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

问题:

如何使模拟工作正常?

P.S。 的 我用Google搜索了 -javaagent:jmockit.jar 选项可能会有所帮助。但它并没有。是否有必要基于1.7 jdk的maven项目?

此外:

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

关于我的演示:

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

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

你可以查看Jetty& JMockit通过兄弟类加载器加载类,因此JMockit根本没有看到Jetty的类

URLClassLoader
|
|-Launcher$AppClassLoader
|-WebAppClassLoader

1 个答案:

答案 0 :(得分:3)

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

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

但是,ForwardingServlet副本被加载到已部署的Web应用程序中(来自文件系统中的“.class”文件,因此不会受到应用的模拟影响JMockit,仅在内存中),使用Jetty的WebAppClassLoader。 JMockit从未见过这个类。

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

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

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

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

    handler.setClassLoader(ClassLoader.getSystemClassLoader());
    

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