2010-06-15 4 views
19

Ich habe Probleme beim Einrichten von JUnit mit App Engine in Eclipse. Ich habe JUnit korrekt eingerichtet, dh ich kann Tests ausführen, die nicht den Datenspeicher oder andere Dienste betreffen. Wenn ich jedoch versuche, den Datenspeicher in meinen Tests zu verwenden, schlagen sie fehl. Der Code, den ich jetzt versuche, ist von der App Engine-Website (siehe unten):Verwenden von JUnit mit App Engine und Eclipse

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

Bisher habe ich die externe JAR-Datei (mit Eclipse) appengine-testing.jar hinzugefügt. Aber wenn ich die Tests durchführe, bekomme ich die Ausnahme unten. Also verstehe ich eindeutig nicht die Anweisungen, um die Dienste von der oben erwähnten Webseite zu aktivieren. Kann jemand die erforderlichen Schritte zur Bereitstellung der App Engine-Dienste in Eclipse ausführen?

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 

Hier ist der eigentliche Code (ziemlich viel von der Website kopiert):

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

Antwort

19

In Eclipse haben Sie alle ergänzten die Gläser here erwähnt? Sie brauchen ein paar Gläser mehr als nur appengine-testing.jar.

Allerdings, wenn Ihre Tests oder im Test befindlichen Code diese Abhängigkeiten haben müssen Sie noch ein paar Gläser auf Ihrem Test Classpath: $ {} SDK_ROOT /lib/impl/appengine-api.jar, $ {SDK_ROOT} /lib/impl/appengine-api-labs.jar und $ {SDK_ROOT} /lib/impl/appengine-api-stubs.jar. Diese JARs stellen die Laufzeit-APIs und die lokalen Implementierungen dieser APIs für Ihre Tests bereit.

+0

Danke Peter, dass der Trick. Die Dokumentation ließ es wie eine Entweder-Oder-Situation klingen (zumindest für mich), aber sobald ich die drei oben erwähnten Gläser hinzugefügt hatte, funktionierte alles. –

+2

Mark und Peter, wie sieht Ihre .classpath-Datei aus? Meine hat Zeilen wie "", aber das funktioniert nicht. Ist "$ {SDK_ROOT}" Code, oder soll ich den Pfad ausfüllen? –

+0

Das löste mein Problem, aber ich musste herausfinden, wo ich die 4 Jar-Dateien finden konnte, auf die in der Lösung von Peter Recore verwiesen wurde. In Eclipse (Juno) ging ich zu Projekt => Eigenschaften => Java Build Path => Bibliotheken => Externe JARs hinzufügen. Dann (auf meinem Mac) habe ich zu Applications \ eclipse \ plugins \ com.google.appengine.eclipse.sdkbundle_1.9.9 \ appengine-java-sdk-1.9.9 \ impl navigiert und die 3 JAR-Dateien ausgewählt. Dann ging ich ein Verzeichnis hoch und runter in das Testverzeichnis, um die 4. JAR zu bekommen, nämlich appengine-testing.jar. –

0

Peter's answer ist richtig: Sie diese Bibliotheken müssen:

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

Die Chancen sind Sie bereits die erste und brauchen nur die letzten drei.

Wenn Sie Maven verwenden, können Sie diese Abhängigkeiten zu pom.xml hinzufügen:

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