Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using JUnit with App Engine and Eclipse

I am having trouble setting up JUnit with App Engine in Eclipse. I have JUnit set up correctly, that is, I can run tests that don't involve the datastore or other services. However, when I try to use the datastore in my tests they fail. The code I am trying right now is from the App Engine site (see below):

http://code.google.com/appengine/docs/java/tools/localunittesting.html#Running_Tests

So far I have added the external JAR (using Eclipse) appengine-testing.jar. But when I run the tests I get the exception below. So, I am clearly not understanding the instructions to enable the services from the web page mentioned above. Can someone clear up the steps needed to make the App Engine services available in Eclipse?

java.lang.NoClassDefFoundError: com/google/appengine/api/datastore/dev/LocalDatastoreService
at com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig.tearDown(LocalDatastoreServiceTestConfig.java:138)
at com.google.appengine.tools.development.testing.LocalServiceTestHelper.tearDown(LocalServiceTestHelper.java:254)
at com.cooperconrad.server.MemberTest.tearDown(MemberTest.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:37)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:73)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.ClassNotFoundException: com.google.appengine.api.datastore.dev.LocalDatastoreService
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
... 25 more

Here is the actual code (pretty much copied from the site):

package com.example;

import static org.junit.Assert.*;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
import com.google.appengine.tools.development.testing.LocalServiceTestHelper;

public class MemberTest
{
    private final LocalServiceTestHelper helper = new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig());

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

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

    // run this test twice to prove we're not leaking any state across tests
    private void doTest() {
        DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
        assertEquals(0, ds.prepare(new Query("yam")).countEntities());
        ds.put(new Entity("yam"));
        ds.put(new Entity("yam"));
        assertEquals(2, ds.prepare(new Query("yam")).countEntities());
    }

    @Test
    public void testInsert1() {
        doTest();
    }

    @Test
    public void testInsert2() {
        doTest();
    }

    @Test
    public void foo()
    {
        assertEquals(4, 2 + 2);
    }
}
like image 361
Mark M Avatar asked Jun 15 '10 22:06

Mark M


2 Answers

In Eclipse, have you added all the jars mentioned here? You need a few more jars than just appengine-testing.jar.

However, if your tests or code under test have these dependencies you'll need a few more JARs on your testing classpath: ${SDK_ROOT}/lib/impl/appengine-api.jar, ${SDK_ROOT}/lib/impl/appengine-api-labs.jar, and ${SDK_ROOT}/lib/impl/appengine-api-stubs.jar. These JARs make the runtime APIs and the local implementations of those APIs available to your tests.

like image 97
Peter Recore Avatar answered Nov 01 '22 15:11

Peter Recore


Peter's answer is correct: you need these libraries:

appengine-api.jar
appengine-api-labs.jar
appengine-api-stubs.jar
appengine-tools-api.jar

Chances are you already have the first one and only need the last three.

If you're using Maven, you can add these dependencies to pom.xml:

<dependency>
  <groupId>com.google.appengine</groupId>
  <artifactId>appengine-api-labs</artifactId>
  <version>1.9.60</version>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>com.google.appengine</groupId>
  <artifactId>appengine-api-stubs</artifactId>
  <version>1.9.60</version>
  <scope>test</scope>
</dependency>

<dependency>
  <groupId>com.google.appengine</groupId>
  <artifactId>appengine-tools-sdk</artifactId>
  <version>1.9.60</version>
  <scope>test</scope>
</dependency>
like image 42
Kevin Workman Avatar answered Nov 01 '22 15:11

Kevin Workman