Search code examples
javaunit-testinghtmlunit

Does this unit test have to be in the same package as the controller it tests?


According to this example, it goes in the same package as the controller it tests.

Why is that necesssary?

I think it would be tidier to have all of my unit tests in a testing package - would there be a problem with doing so?

package com.example.web.controllers;

...imports...

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/testApplicationContext.xml"})
public class HomeControllerSysTest extends AbstractJUnit4SpringContextTests {

    private static final Logger log = Logger.getLogger(
            HomeControllerSysTest.class.getName());
    private final LocalServiceTestHelper helper =
            new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig());

    @Before
    public void setUp() {
        helper.setUp();
    }

    @After
    public void tearDown() {
        helper.tearDown();
    }

    @Test
    public void testHomeController() throws IOException {
        final String url = "http://localhost:8080/movie/test";

        final WebClient webClient = new WebClient();
        final HtmlPage page = webClient.getPage(url);
        assertEquals("The Page Title", page.getTitleText());

        // there are many different methods to query everything on your
        // page. Please refer to the HttpUnit homepage
        HtmlElement header = page.getElementsByTagName("h1").get(0);
        assertNotNull(header);

        String headerValue = header.getNodeValue();
        assertEquals(headerValue, "Hello World!");
    }
}

Solution

  • Unit tests can be in any package. In essence they are just separate classes used to test the behaviour of the class being tested.

    The most important issue here is that placement of the JUnit test classes is a constant for the project they are part of. I.e. either they are always in the same package, or in a sub-package with name test, or in a separate package altogether.

    My preference is to put JUnit test classes in a separate package defined by replacing the top-level name with 'test', so org.util.strings.StingUtil would have a Junit test class named test.util.StringUtilTest.

    This way it is very easy to locate the test classes and they can easily be separated into library .jars and their test .jars. Also you do not run the risk that the JUnit test inadvertantly uses package-level access to the class tested; the test class has to use the same interface as the rest of the world. (In my view package level hooks specifically for test support are evil, so better make sure they are not useful by placing the test elsewhere.)