Cactus Test
Because Cactus is an extension to JUnit, it works in a similar fashion. I write test cases that are then executed by Cactus itself. One major difference is that there are three methods available for each test, and each test can be broken down into three parts: begin, test, and end. The reason for having three separate methods is a little complex.
Cactus works by creating two separate JVM instances. The first instance simulates the client environment; the second instance simulates the server. So a test can cross from the client to the server and back again, all within one test. To further this separation, the methods are run inside of these two instances. Both the begin method and the end method are run inside of the client space, whereas the test method is run within the server space.
Before the first of the three methods is executed, Cactus creates a few objects for me to use. It creates a request object and a response object. Along with these objects, a context is created that can be referenced as well.
With that introduction, here's the Cactus test that tests the validate method of this servlet:
package com.dzrealms.example.servlet; import org.apache.cactus.ServletTestCase; import org.apache.cactus.WebRequest; import org.apache.cactus.WebResponse; /** * Example Cactus Test */ public class ExampleCactusTest extends ServletTestCase { public void beginValidate(WebRequest wr) { wr.addParameter("variable1", "variable1Content"); wr.addParameter("variable2", "variable2Content"); } public void testValidate() throws Exception { ExampleServlet es = new ExampleServlet(); es.init(config); boolean answer = es.validate(request); assertTrue("Received wrong response", answer); } public void endValidate(WebResponse resp) { //We don't do anything here but we could review the response } }
This is a fairly simple test that highlights the basic points. The beginValidate(WebRequest) method is initiated within the client JVM. In this method, the request object is passed in, so I can add any parameters to it that I need. This same object will become available to the test method. I can also construct any objects I may need for client-side testing of my code.
The second method is the server side test. testValidate() will be executed within the server JVM and will have access to the context object, the request object, and the response object. I can pass these objects around just as if I were within the servlet itself. After initializing an instance of the servlet, I call the validate method directly with the global variable request. This variable is the same request object that I populated with values in the beginValidate(WebRequest) method. After I receive the response from the validate method, I execute a JUnit assertion on it to confirm that I received the answer I expected. The test method would also allow me to access any Local Interfaces of any EJBs in the application. Because it is running within the same JVM as the server side code, it is completely appropriate to reference local interfaces and test them here.
In addition to the begin and test methods, there is a third and final step in a test. The end method is passed the response object from this transaction. In this case, I did not do anything to the response object; if I had, it would be appropriate to test the response in this method.