From: Vincent M. <vm...@oc...> - 2001-08-08 12:56:47
|
I was thinking about unit testing Struts Actions. Introduction ------------ Writing a Struts Action is very simple: you simply have to provide a perform method with the following signature : public ActionForward perform(ActionMapping mapping, ActionForm form, ServletRequest request, ServletResponse response) Thus, in order to use Mock Objects for unit testing your action you have to provide mock implementations of : - ActionMapping, - ActionForm, - ServletRequest, - ServletResponse, - ActionServlet : an instance of this class is provided to your action and you can use it to perforl several things. It can be set by calling the setServlet(ActionServlet) method on your Action class. Problem --------- The issue is that Struts initialize internally a lot of objects and put them in different scopes : session, servlet context, request, ..., which is fine. What it simply means is that if you want to unit test your Action class, you'll need to understand in details how Struts works internally and stuff the session, context, ... with the expected values. To do that you'll have to read the source code and spend quite a lot of time (even though Sturts is really well designed by composition). I think this is a major hurdle for using Mock Objects when your object to test is using APIs that are not yours ... Struts is open source so it is feasible to look a the source. For non open-source framework, it is even harder ... The second objection is that doing all this initialization takes a lot of lines of code and is a tiring process. Now, would it be easier with Cactus ? I think so ... for the following reasons. Here is how you would do it with Cactus : ActionServlet servlet = new ActionServlet(); servlet.init(config); (you'll also have to provide a struts-config.xml file but that's fine as you have to write one for Struts anyway). that's all, Struts is initialized ! You don't need to understand how struts works internally. Of course, you could do the same with Mock Objects but you'll no longer be following the Mock Objects principles. Conclusion ----------- Mock Objects has limitations in the following areas : - when the API to mock is not yours and especially if you don't have access to the source code because :; - it takes time to understand how the API works internally - it takes time for every test to initialize the API environment properly. - it is difficult when your class to test is using an Application (as opposed to a framework). A framework is for exemple a logging framework, it contains no state and no business logic, so it is easy to mock. However a framework like Struts is actually an Application : it has state and it has logic, thus you need to understand its internal functioning to mock it. I would very much like to have you thoughts on that, especially if you don't agree ! :) Thanks -Vincent |