1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package servletunit.struts;
18
19 import junit.framework.AssertionFailedError;
20 import junit.framework.TestCase;
21 import org.apache.commons.digester.Digester;
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24 import org.apache.struts.Globals;
25 import org.apache.struts.action.ActionForm;
26 import org.apache.struts.action.ActionServlet;
27 import servletunit.HttpServletRequestSimulator;
28 import servletunit.HttpServletResponseSimulator;
29 import servletunit.ServletConfigSimulator;
30 import servletunit.ServletContextSimulator;
31
32 import javax.servlet.http.*;
33 import java.io.File;
34 import java.io.InputStream;
35 import java.net.URL;
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 public class MockStrutsTestCase extends TestCase {
56
57 protected ActionServlet actionServlet;
58 protected HttpServletRequestSimulator request;
59 protected HttpServletResponseSimulator response;
60 protected HttpServletRequestWrapper requestWrapper;
61 protected HttpServletResponseWrapper responseWrapper;
62 protected ServletContextSimulator context;
63 protected ServletConfigSimulator config;
64 protected String actionPath;
65 protected boolean isInitialized = false;
66 protected boolean actionServletIsInitialized = false;
67 protected boolean requestPathSet = false;
68
69
70
71
72
73
74 protected String registrations[] = {
75 "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN",
76 "/org/apache/struts/resources/web-app_2_2.dtd",
77 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN",
78 "/org/apache/struts/resources/web-app_2_3.dtd"
79 };
80
81
82 protected static Log logger = LogFactory.getLog(MockStrutsTestCase.class);
83
84
85
86
87 public MockStrutsTestCase() {
88 super();
89 }
90
91
92
93
94 public MockStrutsTestCase(String testName) {
95 super(testName);
96 }
97
98
99
100
101
102 private void init() {
103 if (!isInitialized)
104 throw new AssertionFailedError("You are overriding the setUp() method without calling super.setUp(). You must call the superclass setUp() method in your TestCase subclass to ensure proper initialization.");
105 }
106
107
108
109
110
111
112
113 protected void setUp() throws Exception {
114 if (logger.isDebugEnabled())
115 logger.debug("Entering");
116 if (actionServlet == null)
117 actionServlet = new ActionServlet();
118 config = new ServletConfigSimulator();
119 request = new HttpServletRequestSimulator(config.getServletContext());
120 response = new HttpServletResponseSimulator();
121 context = (ServletContextSimulator) config.getServletContext();
122 requestWrapper = null;
123 responseWrapper = null;
124 isInitialized = true;
125 if (logger.isDebugEnabled())
126 logger.debug("Exiting");
127 }
128
129 protected void tearDown() throws Exception {
130 ActionServlet servlet = getActionServlet();
131 servlet.destroy();
132 setActionServlet(servlet);
133 }
134
135
136
137
138
139 public HttpServletRequest getRequest() {
140 if (logger.isDebugEnabled())
141 logger.debug("Entering");
142 init();
143 if (logger.isDebugEnabled())
144 logger.debug("Exiting");
145 return this.request;
146 }
147
148
149
150
151
152
153
154 public HttpServletRequestWrapper getRequestWrapper() {
155 if (logger.isDebugEnabled())
156 logger.debug("Entering");
157 init();
158 if (requestWrapper == null) {
159 if (logger.isDebugEnabled())
160 logger.debug("Exiting");
161 return new HttpServletRequestWrapper(this.request);
162 } else {
163 if (logger.isDebugEnabled()) {
164 logger.debug("wrapper class is '" + requestWrapper.getClass() + "'");
165 }
166 if (logger.isDebugEnabled())
167 logger.debug("Exiting");
168 return requestWrapper;
169 }
170 }
171
172
173
174
175
176
177
178
179
180
181 public void setRequestWrapper(HttpServletRequestWrapper wrapper) {
182 if (logger.isDebugEnabled())
183 logger.debug("Entering - wrapper = " + wrapper);
184 init();
185 if (wrapper == null)
186 throw new IllegalArgumentException("wrapper class cannot be null!");
187 else {
188 if (wrapper.getRequest() == null)
189 wrapper.setRequest(this.request);
190 this.requestWrapper = wrapper;
191 }
192 if (logger.isDebugEnabled())
193 logger.debug("Exiting");
194 }
195
196
197
198
199 public void clearRequestParameters() {
200 if (logger.isTraceEnabled())
201 logger.trace("Entering");
202 this.request.getParameterMap().clear();
203
204
205 response.removeHeader("Location");
206 if (logger.isTraceEnabled())
207 logger.trace("Exiting");
208 }
209
210
211
212
213
214 public HttpServletResponse getResponse() {
215 if (logger.isDebugEnabled())
216 logger.debug("Entering");
217 init();
218 if (logger.isDebugEnabled())
219 logger.debug("Exiting");
220 return this.response;
221 }
222
223
224
225
226
227
228
229 public HttpServletResponseWrapper getResponseWrapper() {
230 if (logger.isDebugEnabled())
231 logger.debug("Entering");
232 init();
233 if (responseWrapper == null) {
234 if (logger.isDebugEnabled())
235 logger.debug("Exiting");
236 return new HttpServletResponseWrapper(this.response);
237 } else {
238 if (logger.isDebugEnabled()) {
239 logger.debug("wrapper class is '" + responseWrapper.getClass() + "'");
240 }
241 if (logger.isDebugEnabled())
242 logger.debug("Exiting");
243 return responseWrapper;
244 }
245 }
246
247
248
249
250
251
252
253
254
255
256 public void setResponseWrapper(HttpServletResponseWrapper wrapper) {
257 if (logger.isDebugEnabled())
258 logger.debug("Entering - wrapper = " + wrapper);
259 init();
260 if (wrapper == null)
261 throw new IllegalArgumentException("wrapper class cannot be null!");
262 else {
263 if (wrapper.getResponse() == null)
264 wrapper.setResponse(this.response);
265 this.responseWrapper = wrapper;
266 }
267 if (logger.isDebugEnabled())
268 logger.debug("Exiting");
269 }
270
271
272
273
274
275
276 public HttpServletRequestSimulator getMockRequest() {
277 if (logger.isTraceEnabled())
278 logger.trace("Entering");
279 init();
280 if (logger.isTraceEnabled())
281 logger.trace("Exiting");
282 return this.request;
283 }
284
285
286
287
288
289
290 public HttpServletResponseSimulator getMockResponse() {
291 if (logger.isTraceEnabled())
292 logger.trace("Entering");
293 init();
294 if (logger.isTraceEnabled())
295 logger.trace("Exiting");
296 return this.response;
297 }
298
299
300
301
302
303 public HttpSession getSession() {
304 if (logger.isDebugEnabled())
305 logger.debug("Entering");
306 init();
307 if (logger.isDebugEnabled())
308 logger.debug("Exiting");
309 return this.request.getSession(true);
310 }
311
312
313
314
315
316
317 public ActionServlet getActionServlet() {
318 if (logger.isDebugEnabled())
319 logger.debug("Entering");
320 init();
321 try {
322 if (!actionServletIsInitialized) {
323 if (logger.isDebugEnabled()) {
324 logger.debug("intializing actionServlet");
325 }
326 this.actionServlet.init(config);
327 actionServletIsInitialized = true;
328 }
329 } catch (Exception e) {
330 logger.error("Error initializing action servlet",e);
331 if(e.getMessage().equals("java.lang.NullPointerException")){
332 String message = "Error initializing action servlet: Unable to find /WEB-INF/web.xml. "
333 + "TestCase is running from " + System.getProperty("user.dir") + " directory. "
334 + "Context directory ";
335 if(this.context.getContextDirectory()==null){
336 message += "has not been set. Try calling setContextDirectory() with a relative or absolute path";
337 }else{
338 message = message + "is " + this.context.getContextDirectory().getAbsolutePath();
339 }
340 message = message + ". /WEB-INF/web.xml must be found under the context directory, "
341 + "the directory the test case is running from, or in the classpath.";
342 fail(message);
343 }else{
344 throw new AssertionFailedError(e.getMessage());
345 }
346 }
347 if (logger.isDebugEnabled())
348 logger.debug("Exiting");
349 return actionServlet;
350 }
351
352
353
354
355
356
357 public void setActionServlet(ActionServlet servlet) {
358 if (logger.isDebugEnabled())
359 logger.debug("Entering - servlet = " + servlet);
360 init();
361 if (servlet == null)
362 throw new AssertionFailedError("Cannot set ActionServlet to null");
363 this.actionServlet = servlet;
364 if (logger.isDebugEnabled())
365 logger.debug("Exiting");
366 actionServletIsInitialized = false;
367 }
368
369
370
371
372
373
374
375
376
377
378
379
380 public void actionPerform() {
381 if (logger.isDebugEnabled())
382 logger.debug("Entering");
383 if(!this.requestPathSet){
384 throw new IllegalStateException("You must call setRequestPathInfo() prior to calling actionPerform().");
385 }
386 init();
387 HttpServletRequest request = this.request;
388 HttpServletResponse response = this.response;
389 if (this.requestWrapper != null)
390 request = this.requestWrapper;
391 if (this.responseWrapper != null)
392 response = this.responseWrapper;
393 try {
394 this.getActionServlet().doPost(request,response);
395 }catch (NullPointerException npe) {
396 String message = "A NullPointerException was thrown. This may indicate an error in your ActionForm, or "
397 + "it may indicate that the Struts ActionServlet was unable to find struts config file. "
398 + "TestCase is running from " + System.getProperty("user.dir") + " directory. "
399 + "Context directory ";
400 if(this.context.getContextDirectory()==null){
401 message += "has not been set. Try calling setContextDirectory() with a relative or absolute path";
402 }else{
403 message = message + "is " + this.context.getContextDirectory().getAbsolutePath();
404 }
405 message = message + ". struts config file must be found under the context directory, "
406 + "the directory the test case is running from, or in the classpath.";
407 throw new ExceptionDuringTestError(message, npe);
408 }catch(Exception e){
409 throw new ExceptionDuringTestError("An uncaught exception was thrown during actionExecute()", e);
410 }
411 if (logger.isDebugEnabled())
412 logger.debug("Exiting");
413 }
414
415
416
417
418
419
420
421 public void addRequestParameter(String parameterName, String parameterValue)
422 {
423 if (logger.isDebugEnabled())
424 logger.debug("Entering - parameterName = " + parameterName + ", parameterValue = " + parameterValue);
425 init();
426 this.request.addParameter(parameterName,parameterValue);
427 if (logger.isDebugEnabled())
428 logger.debug("Exiting");
429 }
430
431
432
433
434
435
436
437 public void addRequestParameter(String parameterName, String[] parameterValues)
438 {
439 if (logger.isDebugEnabled())
440 logger.debug("Entering - parameterName = " + parameterName + ", parameteValue = " + parameterValues);
441 init();
442 this.request.addParameter(parameterName,parameterValues);
443 if (logger.isDebugEnabled())
444 logger.debug("Exiting");
445 }
446
447
448
449
450
451
452
453
454
455 public void setRequestPathInfo(String pathInfo) {
456 if (logger.isDebugEnabled())
457 logger.debug("Entering - pathInfo = " + pathInfo);
458 init();
459 this.setRequestPathInfo("",pathInfo);
460 if (logger.isDebugEnabled())
461 logger.debug("Exiting");
462 }
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478 public void setRequestPathInfo(String moduleName, String pathInfo) {
479 if (logger.isDebugEnabled())
480 logger.debug("Entering - moduleName = " + moduleName + ", pathInfo = " + pathInfo);
481 init();
482 this.actionPath = Common.stripActionPath(pathInfo);
483 if (moduleName != null) {
484 if (!moduleName.equals("")) {
485 if (!moduleName.startsWith("/"))
486 moduleName = "/" + moduleName;
487 if (!moduleName.endsWith("/"))
488 moduleName = moduleName + "/";
489 }
490 if (logger.isDebugEnabled()) {
491 logger.debug("setting request attribute - name = " + Common.INCLUDE_SERVLET_PATH + ", value = " + moduleName);
492 }
493 this.request.setAttribute(Common.INCLUDE_SERVLET_PATH, moduleName);
494 }
495 this.request.setPathInfo(actionPath);
496 this.requestPathSet = true;
497 if (logger.isDebugEnabled())
498 logger.debug("Exiting");
499 }
500
501
502
503
504
505
506
507
508
509 public void setInitParameter(String key, String value){
510 if (logger.isDebugEnabled())
511 logger.debug("Entering - key = " + key + ", value = " + value);
512 init();
513 config.setInitParameter(key, value);
514 actionServletIsInitialized = false;
515 if (logger.isDebugEnabled())
516 logger.debug("Exiting");
517 }
518
519
520
521
522
523
524
525 public void setContextDirectory(File contextDirectory) {
526 if (logger.isDebugEnabled())
527 logger.debug("Entering - contextDirectory = " + contextDirectory);
528 init();
529 context.setContextDirectory(contextDirectory);
530 actionServletIsInitialized = false;
531 if (logger.isDebugEnabled())
532 logger.debug("Exiting");
533 }
534
535
536
537
538
539
540
541 public void setConfigFile(String pathname) {
542 if (logger.isDebugEnabled())
543 logger.debug("Entering - pathName = " + pathname);
544 init();
545 setConfigFile(null,pathname);
546 if (logger.isDebugEnabled())
547 logger.debug("Exiting");
548 }
549
550
551
552
553
554
555
556
557
558
559 public void setConfigFile(String moduleName, String pathname) {
560 if (logger.isDebugEnabled())
561 logger.debug("Entering - moduleName = " + moduleName + ", pathname =" + pathname);
562 init();
563 if (moduleName == null)
564 this.config.setInitParameter("config",pathname);
565 else
566 this.config.setInitParameter("config/" + moduleName,pathname);
567 actionServletIsInitialized = false;
568 if (logger.isDebugEnabled())
569 logger.debug("Exiting");
570 }
571
572
573
574
575
576
577
578
579
580
581 public void setServletConfigFile(String pathname) {
582 if (logger.isDebugEnabled())
583 logger.debug("Entering - pathname = " + pathname);
584 init();
585
586
587
588 Digester digester = new Digester();
589 digester.push(this.config);
590 digester.setValidating(true);
591 digester.addCallMethod("web-app/servlet/init-param", "setInitParameter", 2);
592 digester.addCallParam("web-app/servlet/init-param/param-name", 0);
593 digester.addCallParam("web-app/servlet/init-param/param-value", 1);
594 try {
595 for (int i = 0; i < registrations.length; i += 2) {
596 URL url = context.getResource(registrations[i + 1]);
597 if (url != null)
598 digester.register(registrations[i], url.toString());
599 }
600 InputStream input = context.getResourceAsStream(pathname);
601 if(input==null)
602 throw new AssertionFailedError("Invalid pathname: " + pathname);
603 digester.parse(input);
604 input.close();
605 } catch (Exception e) {
606 throw new AssertionFailedError("Received an exception while loading web.xml - " + e.getClass() + " : " + e.getMessage());
607 }
608
609
610 digester = new Digester();
611 digester.setValidating(true);
612 digester.push(this.context);
613 digester.addCallMethod("web-app/context-param", "setInitParameter", 2);
614 digester.addCallParam("web-app/context-param/param-name", 0);
615 digester.addCallParam("web-app/context-param/param-value", 1);
616 try {
617 for (int i = 0; i < registrations.length; i += 2) {
618 URL url = context.getResource(registrations[i + 1]);
619 if (url != null)
620 digester.register(registrations[i], url.toString());
621 }
622 InputStream input = context.getResourceAsStream(pathname);
623 if(input==null)
624 throw new AssertionFailedError("Invalid pathname: " + pathname);
625 digester.parse(input);
626 input.close();
627 } catch (Exception e) {
628 throw new AssertionFailedError("Received an exception while loading web.xml - " + e.getClass() + " : " + e.getMessage());
629 }
630 actionServletIsInitialized = false;
631 if (logger.isDebugEnabled())
632 logger.debug("Exiting");
633 }
634
635
636
637
638 protected String getActualForward() {
639 if (logger.isDebugEnabled())
640 logger.debug("Entering");
641 if (response.containsHeader("Location")) {
642 return Common.stripJSessionID(response.getHeader("Location"));
643 } else
644 try {
645 String strippedForward = request.getContextPath() + Common.stripJSessionID(((ServletContextSimulator) config.getServletContext()).getRequestDispatcherSimulator().getForward());
646 if (logger.isDebugEnabled()) {
647 logger.debug("stripped forward and added context path - " + strippedForward);
648 }
649 if (logger.isDebugEnabled())
650 logger.debug("Exiting");
651 return strippedForward;
652 } catch (NullPointerException npe) {
653 if (logger.isDebugEnabled()) {
654 logger.debug("caught NullPointerException - returning null",npe);
655 }
656 return null;
657 }
658 }
659
660
661
662
663
664
665
666
667
668
669
670
671 public void verifyForward(String forwardName) throws AssertionFailedError {
672 if (logger.isDebugEnabled())
673 logger.debug("Entering - forwardName = " + forwardName);
674 init();
675 Common.verifyForwardPath(actionPath,forwardName,getActualForward(),false,request,config.getServletContext(),config);
676 if (logger.isDebugEnabled())
677 logger.debug("Exiting");
678 }
679
680
681
682
683
684
685
686
687
688
689
690
691 public void verifyForwardPath(String forwardPath) throws AssertionFailedError {
692 if (logger.isDebugEnabled())
693 logger.debug("Entering - forwardPath = " + forwardPath);
694 init();
695 String actualForward = getActualForward();
696 if ((actualForward == null) && (forwardPath == null)) {
697
698 return;
699 }
700
701 forwardPath = request.getContextPath() + forwardPath;
702
703 if (actualForward == null) {
704 if (logger.isDebugEnabled()) {
705 logger.debug("actualForward is null - this usually means it is not mapped properly.");
706 }
707 throw new AssertionFailedError("Was expecting '" + forwardPath + "' but it appears the Action has tried to return an ActionForward that is not mapped correctly.");
708 }
709 if (logger.isDebugEnabled()) {
710 logger.debug("expected forward = '" + forwardPath + "' - actual forward = '" + actualForward + "'");
711 }
712 if (!(actualForward.equals(forwardPath)))
713 throw new AssertionFailedError("was expecting '" + forwardPath + "' but received '" + actualForward + "'");
714 if (logger.isDebugEnabled())
715 logger.debug("Exiting");
716 }
717
718
719
720
721
722
723
724
725
726 public void verifyInputForward() {
727 if (logger.isDebugEnabled())
728 logger.debug("Entering");
729 init();
730 Common.verifyForwardPath(actionPath,null,getActualForward(),true,request,config.getServletContext(),config);
731 if (logger.isDebugEnabled())
732 logger.debug("Exiting");
733 }
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749 public void verifyTilesForward(String forwardName, String definitionName) {
750 if (logger.isTraceEnabled())
751 logger.trace("Entering - forwardName=" + forwardName + ", definitionName=" + definitionName);
752 init();
753 Common.verifyTilesForward(actionPath,forwardName,definitionName,false,request,config.getServletContext(),config);
754 if (logger.isTraceEnabled())
755 logger.trace("Exiting");
756 }
757
758
759
760
761
762
763
764
765
766
767
768
769 public void verifyInputTilesForward(String definitionName) {
770 if (logger.isTraceEnabled())
771 logger.trace("Entering - definitionName=" + definitionName);
772 init();
773 Common.verifyTilesForward(actionPath,null,definitionName,true,request,config.getServletContext(),config);
774 if (logger.isTraceEnabled())
775 logger.trace("Exiting");
776 }
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792 public void verifyActionErrors(String[] errorNames) {
793 if (logger.isDebugEnabled())
794 logger.debug("errorNames = " + errorNames);
795 init();
796 Common.verifyActionMessages(request,errorNames,Globals.ERROR_KEY,"error");
797 if (logger.isDebugEnabled())
798 logger.debug("Exiting");
799 }
800
801
802
803
804
805
806
807
808
809 public void verifyNoActionErrors() {
810 if (logger.isDebugEnabled())
811 logger.debug("Entering");
812 init();
813 Common.verifyNoActionMessages(request,Globals.ERROR_KEY,"error");
814 if (logger.isDebugEnabled())
815 logger.debug("Exiting");
816 }
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831 public void verifyActionMessages(String[] messageNames) {
832 if (logger.isDebugEnabled())
833 logger.debug("Entering - messageNames = " + messageNames);
834 init();
835 Common.verifyActionMessages(request,messageNames,Globals.MESSAGE_KEY,"action");
836 if (logger.isDebugEnabled())
837 logger.debug("Exiting");
838 }
839
840
841
842
843
844
845
846
847 public void verifyNoActionMessages() {
848 if (logger.isDebugEnabled())
849 logger.debug("Entering");
850 init();
851 Common.verifyNoActionMessages(request,Globals.MESSAGE_KEY,"action");
852 if (logger.isDebugEnabled())
853 logger.debug("Exiting");
854 }
855
856
857
858
859
860
861
862
863 public ActionForm getActionForm() {
864 if (logger.isDebugEnabled())
865 logger.debug("Entering");
866 init();
867 if (logger.isDebugEnabled())
868 logger.debug("Exiting");
869 return Common.getActionForm(actionPath,request,context);
870 }
871
872
873
874
875
876
877
878
879
880
881
882 public void setActionForm(ActionForm form) {
883 if (logger.isDebugEnabled())
884 logger.debug("Entering - form = " + form);
885 init();
886
887 getActionServlet();
888 Common.setActionForm(form,request,actionPath,context);
889 if (logger.isDebugEnabled())
890 logger.debug("Exiting");
891 }
892
893
894
895
896 }
897