{"id":25,"date":"2007-07-30T10:39:00","date_gmt":"2007-07-30T10:39:00","guid":{"rendered":"http:\/\/euve3303.vserver.de\/stefan\/blog\/?p=28"},"modified":"2011-12-02T20:38:32","modified_gmt":"2011-12-02T19:38:32","slug":"testen-mit-httpunit-und-spring","status":"publish","type":"post","link":"https:\/\/cogito-ergo-blog.de\/blog\/2007\/07\/30\/testen-mit-httpunit-und-spring\/","title":{"rendered":"Testen mit HttpUnit und Spring"},"content":{"rendered":"<p>Beim Testen mit HttpUnit und Spring m\u00fcssen die Servlets und Filter, die \u00fcber Spring konfiguriert werden mit ihrem Context versorgt werden. Nimmt man hierzu den &#8220;normalen&#8221; Context-Listener von Spring, hat das den Nachteil, dass bei jedem Start des HttpUnit-ServletContainers der Context neugeladen wird, was unter Umst\u00e4nden viel Zeit in Anspruch nimmt.\n<\/p>\n<h3>Context cachen<\/h3>\n<p>Das Zwischenspeichern des Context ist erforderlich und \u00e4hnlich wie Spring selbst Basisklassen mit dieser Eigenschaft anbietet, kann auch ein ContextListener geschrieben werden, der den Context speichert und f\u00fcr viele Testruns zu Verf\u00fcgung stellt.<\/p>\n<p><!--more--><\/p>\n<p>Ein solcher Listener sieht z.B. so aus:<\/p>\n<blockquote style=\"border: 1px solid gray; overflow: auto; font-size: 100%; height: 300px; background-color: rgb(238, 238, 238);\">\n<pre>\r\n<tt class=\"java\"><span class=\"java4\">package <\/span><span class=\"java10\">com.rinke.solutions.spring.test;\r\n\r\n<\/span><span class=\"java4\">import <\/span><span class=\"java10\">javax.servlet.ServletContext;\r\n<\/span><span class=\"java4\">import <\/span><span class=\"java10\">javax.servlet.ServletContextEvent;\r\n<\/span><span class=\"java4\">import <\/span><span class=\"java10\">javax.servlet.ServletContextListener;\r\n\r\n<\/span><span class=\"java4\">import <\/span><span class=\"java10\">org.springframework.beans.BeansException;\r\n<\/span><span class=\"java4\">import <\/span><span class=\"java10\">org.springframework.context.support.ClassPathXmlApplicationContext;\r\n<\/span><span class=\"java4\">import <\/span><span class=\"java10\">org.springframework.web.context.WebApplicationContext;\r\n\r\n<\/span><span class=\"java14\">\/**\r\n * class that creates and caches an instance of a WebApplicationContext that can act as listener\r\n * in a httpunit test environment. so the context is reused by all tests which is much faster than\r\n * reinstanciate it again and again.\r\n * <\/span><span class=\"java11\">@author <\/span><span class=\"java14\">Stefan Rinke\r\n *\/\r\n<\/span><span class=\"java4\">public class <\/span><span class=\"java10\">CachingApplicationContextServletContextListener <\/span><span class=\"java4\">implements <\/span><span class=\"java10\">ServletContextListener <\/span><span class=\"java8\">{\r\n\r\n&#xA0;&#xA0;&#xA0; <\/span><span class=\"java14\">\/**\r\n&#xA0;&#xA0;&#xA0;&#xA0; * the instance shared by all tests.\r\n&#xA0;&#xA0;&#xA0;&#xA0; *\/\r\n&#xA0;&#xA0;&#xA0; <\/span><span class=\"java4\">private static <\/span><span class=\"java10\">WebApplicationContext ctx;\r\n\r\n&#xA0;&#xA0;&#xA0; <\/span><span class=\"java14\">\/**\r\n&#xA0;&#xA0;&#xA0;&#xA0; * An implemetation of WebApplicationContext that allows the expiclit setting of the servlet\r\n&#xA0;&#xA0;&#xA0;&#xA0; * context (maybe a mocked context).\r\n&#xA0;&#xA0;&#xA0;&#xA0; * <\/span><span class=\"java11\">@author <\/span><span class=\"java14\">ster\r\n&#xA0;&#xA0;&#xA0;&#xA0; *\/\r\n&#xA0;&#xA0;&#xA0; <\/span><span class=\"java4\">public static class <\/span><span class=\"java10\">MyWebApplicationContext <\/span><span class=\"java4\">extends <\/span><span class=\"java10\">ClassPathXmlApplicationContext <\/span><span class=\"java4\">implements <\/span><span class=\"java10\">WebApplicationContext <\/span><span class=\"java8\">{\r\n\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java14\">\/**\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; * creates the context an loads the context definition from a classpath location.\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; * <\/span><span class=\"java11\">@param <\/span><span class=\"java14\">loc the class path relative location of the context definition.\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; * <\/span><span class=\"java11\">@throws <\/span><span class=\"java14\">BeansException if initialization fails\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; *\/\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java4\">public <\/span><span class=\"java10\">MyWebApplicationContext<\/span><span class=\"java8\">(<\/span><span class=\"java10\">String loc<\/span><span class=\"java8\">) <\/span><span class=\"java4\">throws <\/span><span class=\"java10\">BeansException <\/span><span class=\"java8\">{\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java4\">super<\/span><span class=\"java8\">(<\/span><span class=\"java10\">loc<\/span><span class=\"java8\">)<\/span><span class=\"java10\">;\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java8\">}\r\n\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java14\">\/**\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; * stores the servlet context instance as a ThreadLocal, so that different thread can share\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; * the WebApplicationContext and use different servlet contexts.\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; *\/\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java4\">private <\/span><span class=\"java10\">ThreadLocal servletContext = <\/span><span class=\"java4\">new <\/span><span class=\"java10\">ThreadLocal<\/span><span class=\"java8\">()<\/span><span class=\"java10\">;\r\n\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java14\">\/**\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; * return my servlet context for this thread.\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; * <\/span><span class=\"java11\">@see <\/span><span class=\"java14\">org.springframework.web.context.WebApplicationContext#getServletContext()\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; *\/\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java4\">public <\/span><span class=\"java10\">ServletContext getServletContext<\/span><span class=\"java8\">() {\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java4\">return <\/span><span class=\"java8\">(<\/span><span class=\"java10\">ServletContext<\/span><span class=\"java8\">) <\/span><span class=\"java10\">servletContext.get<\/span><span class=\"java8\">()<\/span><span class=\"java10\">;\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java8\">}\r\n\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java14\">\/**\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; * set the servlet context, which is presented to all 'clients' of the WebApplicationContext.\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; * <\/span><span class=\"java11\">@param <\/span><span class=\"java14\">servletContext the context to use\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; *\/\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java16\">@SuppressWarnings<\/span><span class=\"java8\">(<\/span><span class=\"java5\">&#34;unchecked&#34;<\/span><span class=\"java8\">)\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java4\">public <\/span><span class=\"java9\">void <\/span><span class=\"java10\">setServletContext<\/span><span class=\"java8\">(<\/span><span class=\"java10\">ServletContext servletContext<\/span><span class=\"java8\">) {\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java4\">this<\/span><span class=\"java10\">.servletContext.set<\/span><span class=\"java8\">( <\/span><span class=\"java10\">servletContext <\/span><span class=\"java8\">)<\/span><span class=\"java10\">;\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java8\">}\r\n\r\n&#xA0;&#xA0;&#xA0; }\r\n\r\n&#xA0;&#xA0;&#xA0; <\/span><span class=\"java14\">\/**\r\n&#xA0;&#xA0;&#xA0;&#xA0; * static factory for the singleton WebApplicationContext\r\n&#xA0;&#xA0;&#xA0;&#xA0; * <\/span><span class=\"java11\">@return <\/span><span class=\"java14\">the new or cached context\r\n&#xA0;&#xA0;&#xA0;&#xA0; *\/\r\n&#xA0;&#xA0;&#xA0; <\/span><span class=\"java4\">public synchronized static <\/span><span class=\"java10\">WebApplicationContext getApplicationContext<\/span><span class=\"java8\">() {\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java4\">if<\/span><span class=\"java8\">( <\/span><span class=\"java10\">ctx == <\/span><span class=\"java4\">null <\/span><span class=\"java8\">) {\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java10\">ctx = <\/span><span class=\"java4\">new <\/span><span class=\"java10\">MyWebApplicationContext<\/span><span class=\"java8\">(<\/span><span class=\"java5\">&#34;\/testContext.xml&#34;<\/span><span class=\"java8\">)<\/span><span class=\"java10\">;\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java8\">}\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java4\">return <\/span><span class=\"java10\">ctx;\r\n&#xA0;&#xA0;&#xA0; <\/span><span class=\"java8\">}\r\n\r\n&#xA0;&#xA0;&#xA0; <\/span><span class=\"java14\">\/**\r\n&#xA0;&#xA0;&#xA0;&#xA0; * listener callback. populates the cached context with the new initializing servlet context.\r\n&#xA0;&#xA0;&#xA0;&#xA0; * <\/span><span class=\"java11\">@see <\/span><span class=\"java14\">javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)\r\n&#xA0;&#xA0;&#xA0;&#xA0; *\/\r\n&#xA0;&#xA0;&#xA0; <\/span><span class=\"java4\">public <\/span><span class=\"java9\">void <\/span><span class=\"java10\">contextInitialized<\/span><span class=\"java8\">(<\/span><span class=\"java10\">ServletContextEvent evt<\/span><span class=\"java8\">) {\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; <\/span><span class=\"java10\">MyWebApplicationContext ctx = <\/span><span class=\"java8\">(<\/span><span class=\"java10\">MyWebApplicationContext<\/span><span class=\"java8\">) <\/span><span class=\"java10\">CachingApplicationContextServletContextListener.getApplicationContext<\/span><span class=\"java8\">()<\/span><span class=\"java10\">;\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; ctx.setServletContext<\/span><span class=\"java8\">(<\/span><span class=\"java10\">evt.getServletContext<\/span><span class=\"java8\">())<\/span><span class=\"java10\">;\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; evt.getServletContext<\/span><span class=\"java8\">()<\/span><span class=\"java10\">.setAttribute<\/span><span class=\"java8\">( <\/span><span class=\"java10\">WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,\r\n&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0; ctx <\/span><span class=\"java8\">)<\/span><span class=\"java10\">;\r\n&#xA0;&#xA0;&#xA0; <\/span><span class=\"java8\">}\r\n\r\n&#xA0;&#xA0;&#xA0; <\/span><span class=\"java14\">\/**\r\n&#xA0;&#xA0;&#xA0;&#xA0; * does nothing\r\n&#xA0;&#xA0;&#xA0;&#xA0; * <\/span><span class=\"java11\">@see <\/span><span class=\"java14\">javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)\r\n&#xA0;&#xA0;&#xA0;&#xA0; *\/\r\n&#xA0;&#xA0;&#xA0; <\/span><span class=\"java4\">public <\/span><span class=\"java9\">void <\/span><span class=\"java10\">contextDestroyed<\/span><span class=\"java8\">(<\/span><span class=\"java10\">ServletContextEvent arg0<\/span><span class=\"java8\">) {\r\n&#xA0;&#xA0;&#xA0; }\r\n\r\n}<\/span><\/tt>\r\n<\/pre>\n<\/blockquote>\n<p>\nEin weiterer Vorteil des eigenen Listeners: man kann die Context-Definition laden wie man will und ist nicht abh\u00e4ngig, von dem simulierten Verhalten des Servlet-Classloaders von HttpUnit.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Beim Testen mit HttpUnit und Spring m\u00fcssen die Servlets und Filter, die \u00fcber Spring konfiguriert werden mit ihrem Context versorgt werden. Nimmt man hierzu den &#8220;normalen&#8221; Context-Listener von Spring, hat das den Nachteil, dass bei jedem Start des HttpUnit-ServletContainers der &hellip; <a href=\"https:\/\/cogito-ergo-blog.de\/blog\/2007\/07\/30\/testen-mit-httpunit-und-spring\/\">Weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[],"_links":{"self":[{"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/posts\/25"}],"collection":[{"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/comments?post=25"}],"version-history":[{"count":1,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/posts\/25\/revisions"}],"predecessor-version":[{"id":10019,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/posts\/25\/revisions\/10019"}],"wp:attachment":[{"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/media?parent=25"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/categories?post=25"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cogito-ergo-blog.de\/blog\/wp-json\/wp\/v2\/tags?post=25"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}