Unitary tests

If you use dependency injection through constructors and method parameters, it becomes easy to create your unitary test, i.e.:

@Component("sum")
public class Sum {
        private int result;
        
        public void sum(int first, int second) {
                this.result = first + second;
        }
        
        public int getResult() {
                return this.result;
        }
}

public class SumTest extends TestCase {

        public void testSumsCorrectlyLowNumbers() {
                int expected = 1999;
                Sum logic = new Sum();
                logic.sum(1000, 999);
                assertEquals(expected, logic.getResult());
        }
        
}

Full browser testing

You can use Selenium to fully test your system through Junit testcases using an specific browser.

Functional/Integration testing

VRaptor focused also on your logic functional-testing.

Most frameworks (Struts, Webwork and so on) leave it to the programmer: instantiate it, simulate the magic yourself, call your method!

But calling a setter on your own is not the same as using a converter! You can see other examples:

  1. Struts extension for junit, check out the testing code size for a simple forward validation!
  2. Struts example using cactus, check ouy the example size for a simple test!
  3. Spring example

    Most of the code showed in previous examples are there simply because there is no convention on some issues (like struts-config.xml file, which can be changed)...

VRaptor's choice

VRaptor's TestEngine emulates VRaptor in a test enviroment in order to create functional tests for your business logic components. It tests vraptor integration with your business logics.

Creating a test class

Create a test class called TestPersonLogic to test the validation tutorial.

Inside it, let's instantiate the TestEngine, but be careful: it loads all xml files therefore it might be a good idea to not instantiate it more than once for your tests: (use good sense).

public class TestPersonLogic extends TestCase {

        private static final TestEngine ENGINE = TestEngine.createEngine(
                        new MockedServletContext("WebContent"));

}

The MockedServletContex is a mock context which is used by the TestEngine to simulate the servlet context. You should pass the web target folder name to the constructor, in our example WebContent.

Request sequence

A functional test requires one or more requests so more advanced tests are available (with user session support and so on).

To create a user session (the same as opening a browser window, a http session) use:

                TestSession session = ENGINE.createSession();

A simple valid request

A valid request to our example would be to call person.add.logic with parameters person.name=Guilherme, person.address=Vergueiro and person.preferredNumber=5.

So what about executing the mentioned request?

                String result = session.execute("person.add.logic",
                                "person.name=Guilherme", "person.address=Vergueiro",
                                "person.preferredNumber=5");

Let's assert it returns ok (or null, remember: the default value is ok):

                assertEquals("ok",result);

The result

The final class to test the ok result is:

package org.vraptor.examples.first;

import junit.framework.TestCase;

import org.vraptor.VRaptorException;
import org.vraptor.test.TestEngine;
import org.vraptor.test.TestSession;

public class TestPersonLogic extends TestCase {

        private static final TestEngine ENGINE = TestEngine.createEngine();

        public void testAddsANewPerson() throws VRaptorException {
                TestSession session = ENGINE.createSession();
                String result = session.execute("person.add.logic",
                                "person.name=Guilherme", "person.address=Vergueiro",
                                "person.preferredNumber=5");
                assertEquals("ok",result);
        }

}

Validation errors

Let's continue and test the validation process (do it after you have done the validation tutorial):

If we send only two parameters, it should return invalid, so let's try them:

        public void testComplainsAboutNameError() throws VRaptorException {
                TestSession session = ENGINE.createSession();
                String result = session.execute("person.add.logic",
                                "person.address=Vergueiro", "person.preferredNumber=5");
                assertEquals("invalid",result);
        }

        public void testComplainsAboutAddressError() throws VRaptorException {
                TestSession session = ENGINE.createSession();
                String result = session.execute("person.add.logic",
                                "person.name=Guilherme", "person.preferredNumber=5");
                assertEquals("invalid",result);
        }

        public void testComplainsAboutNumberError() throws VRaptorException {
                TestSession session = ENGINE.createSession();
                String result = session.execute("person.add.logic",
                                "person.name=Guilherme", "person.address=Vergueiro");
                assertEquals("invalid",result);
        }

Separate the Testing Output Folder

Please separate your output folder for test classes from other application classes. If not, VRaptor class loader will get in conflict with the TestEngine and your web app will not load.