我在集成测试中使用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
答案 0 :(得分:3)
示例项目中的JUnit测试正在尝试模拟ForwardingServlet
类。但是,在这种带有嵌入式Jetty Web服务器的场景中,实际上有这个类的两个实例,它们都加载在同一个JVM中但是通过不同的类加载器。
该类的第一个实例由常规类加载器加载,通过该类加载器从启动JUnit测试运行器(AppClassLoader
)的线程加载类。因此,当ForwardingServlet
出现在测试代码中时,它就是在此类加载器中定义的那个。这是给JMockit模拟的类,这正是发生的事情。
但是,ForwardingServlet
的副本被加载到已部署的Web应用程序中(来自文件系统中的“.class”文件,因此不会受到应用的模拟影响JMockit,仅在内存中),使用Jetty的WebAppClassLoader
。 JMockit从未见过这个类。
这个问题有两种可能的解决方案:
以某种方式获取WebAppClassLoader
加载的类对象,然后通过调用MockUp(Class)
构造函数来模拟它。
配置Jetty服务器,使其不为Web应用程序中的类使用自定义类加载器。
第二个解决方案是最简单的,只需在ContextHandler
对象创建的WebArchive
对象上添加以下调用,然后将处理程序设置为Jetty Server
即可。对象:
handler.setClassLoader(ClassLoader.getSystemClassLoader());
我对此进行了测试,并按预期工作,@Mock doGet(...)
方法被执行而不是ForwardingServlet
中的真实方法。