开发者

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);
    }
}


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.


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>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜