Unit tests + injection

From: Andrus Adamchik (andru..bjectstyle.org)
Date: Mon Jun 14 2010 - 14:17:41 UTC

  • Next message: Andrus Adamchik: "Re: Build failed in Hudson: Cayenne-trunk » HSQLDB,JDK 1.6 (latest),Ubuntu #327"

    Did a bit of unit test hacking while on the plane last night. Just
    checked in some pretty good early results. We are still bound by JUnit
    3 lifecycle simplicity and have to use static singletons, still I was
    able to build a little framework for dependency injection into the
    test cases, with access to the new DI Cayenne stack. Underneath that
    is an old CayenneResources singleton that loads DB connection,
    generates the schema, etc...

    Still the unit test "frontend" is now drastically different (see e.g.
    DataContextEJBQLConditionsTest, one of the few tests that I switched).
    Tests extending DICase (or its subclass - ServerCase) can use..nject
    annotations to get access to the interesting parts of the stack being
    tested (in 90% of cases that I converted so far this would be
    ObjectContext and DBHelper) in a clean manner that does not obfuscate
    the test purpose. I also replaced Spring/XML data sets with DBHelper.
    So a typical DB-aware test case may look like
    DataContextEJBQLConditionsTest:

    @UseServerRuntime(ServerCase.TESTMAP_PROJECT)
    public class DataContextEJBQLConditionsTest extends ServerCase {

        ..nject
         protected ObjectContext context;

        ..nject
         protected DBHelper dbHelper;

         protected TableHelper tArtist;

        ..verride
         protected void setUpAfterInjection() throws Exception {
             dbHelper.deleteAll("PAINTING_INFO");
             ...
             tArtist = new TableHelper(dbHelper, "ARTIST");
             tArtist.setColumns("ARTIST_ID", "ARTIST_NAME");
             ...
         }

         protected void createDataSetXYZ() throws Exception {
             tArtist.insert(33001, "B");
             tArtist.insert(33002, "A");
             tArtist.insert(33003, "D");

             tPainting.insert(33009, 33001, "X", 5000);
             tPainting.insert(33010, 33001, "Y", 5000);
             tPainting.insert(33011, 33002, "Z", 5000);
         }

         public void testSomething() throws Exception {
             createDataSetXYZ();

             // normal unit test goes here
             ...
         }

    It is much cleaner than what we had before at the unit test level at
    the expense of a few trivial DI providers in the DI backend.

    In general I feel like the Cayenne DI container is a cool little piece
    of technology that will take us pretty far in many areas of the
    framework. It is still only 36K in size and has simplicity as its main
    design paradigm. The only major feature that it is missing compared to
    the other guys is method interception, and we can add that down the
    road if we feel compelled to have it for Cayenne uses.

    Cheers,
    Andrus



    This archive was generated by hypermail 2.0.0 : Mon Jun 14 2010 - 14:18:21 UTC