views:

37

answers:

3

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!");
    }
}
+2  A: 

Keeping them in the same package allows testing of package-private objects and methods. To keep things tidy, put tests in the "same" package by creating a parallel source tree.

src/
  com/
    example/
      MyClass.java

tests/
  com/
    example/
      MyClassTest.java

Both source trees can be compiled to the same output directory or otherwise added to the classpath, resulting in them being in the same package as far as the JVM is concerned.

bemace
+1  A: 

Does it have to be? No.

Should it be? That's the convention.

When jarring for production, Ant tasks with the proper attributes can remove all the test classes no matter how you organize your project. So the physical location doesn't much matter in this regard.

For normal 'source' jarring, it's nicer to have the test cases in close proximity to the related source code so you can more easily make source releases.

Java has package-level access (similar to private and public access) but I don't think this is used too often.

The big thing is that you have unit tests. The rest isn't so important IMO.

Tony Ennis
+1  A: 

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.)

rsp
What about testing things that you *want* to be package-level?
bemace
Package level access is a restricted part of the implementation, like `protected`. If you need package level acces in a test you can use an anonymous subclass in your JUnit testmethod providing that access.
rsp
+1 for renaming the top-level name in the package. I just "junit" or "htmlunit" myself, depending on which tool the tests are based on.
Rodney Gitzel