Thursday, October 21, 2010

Google AppEngine JUnit tests that use JDO persistence

Google AppEngine has a very clear article on setting up local unit tests. It even says how to setup Datastore tests. What it doesn't say explicitly is that this means JDO will auto-magically work too. Naive idiots (self) therefore assume there is some magic incantation that makes it work. Or that it just doesn't work, but that doesn't really seem likely. To further confuse us, the internets abound with complex solutions for getting a PersistenceManager at test-time. Ignore all the noise; it is as simple as setting up the Datastore and just using JDO as normal. In more detail:
  1. As per Google instructions, make sure appengine-testing.jar, appengine-api-labs.jar, and appengine-api-stubs.jar are on your classpath
  2. Setup a datastore for testing, again just as in Googles instructions
  3. Run your test using a PersistenceManager just as you would normally (assuming you have a PMF setup as per Google's example)
    import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
    import com.google.appengine.tools.development.testing.LocalServiceTestHelper;
    public class MyTestClass {
        private final LocalServiceTestHelper helper =
            new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig());
    
        @Before
        public void setUp() {
            helper.setUp();        
        }
    
        @After
        public void tearDown() {
            helper.tearDown();
        }
    
     @Test
     public void simpleJdo() {
      MyObject t = new MyObject("test");
      
      PersistenceManager pm;
      
      //prove MyObject doesn't span tests
      pm = PMF.getPm();
      boolean notFound = false;
      try {
       pm.getObjectById(MyObject.class, "test");
       fail("should have raised not found");
      } catch (JDOObjectNotFoundException e) {
       notFound = true;
      } finally {
       pm.close();
      }
      assertTrue(notFound);
      
      pm = PMF.getPm();
      try {
       pm.makePersistent(t);
      } finally {
       pm.close();
      }
      
      pm = PMF.getPm();
      try {
       t = pm.getObjectById(MyObject.class, "test");
      } finally {
       pm.close();
      }
      
      assertNotNull(pm);
      assertEquals("test", t.getName());
     }
    }
    
  4. Yay!

3 comments:

seriemajp said...

Just what I was experiencing. Thanks for ending my frustration!

Tim H said...

Thanks for clearing this up. I was getting confused by the workarounds people were coming up with. It's good to know that the LocalServiceTestHelper class loaded with the LocalDatastoreServiceTestConfig configuration can setup and teardown an in-memory datastore that is also used by the persistence manager layer.

Naviya Nair said...

I have read your blog its very attractive and impressive. I like it your blog.

Java Online Training Java EE Online Training Java EE Online Training Java 8 online training Core Java 8 online training

Java Online Training from India Java Online Training from India Core Java Training Online Core Java Training Online Java Training InstitutesJava Training Institutes

Post a Comment