I want to do some automated datastore tests for the Google App Engine locally with Junit.
I have written a class ‘Agent.java’ with three Strings ‘name’, ‘owner’ and ‘url’. The class ‘Player’ is abstract, but does not provide additional attributes.
public class Agent extends Player implements Serializable {
/** to serialize Agent */
private static final long serialVersionUID = -6859912740484191335L;
/** The name of the Agent is the key-element of the agent-class*/
@Id String name;
/** Url to the Agent */
String url;
@Index String owner;
...
Followed by Setters and Getters.
I have copied the 4 needed library from the sdk 1.6.0 to the projects ‘war/WEB-INF/lib’ folder and included the Junit4 Container.
My test class looks like this:
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.logging.Logger;
import org.junit.BeforeClass;
import org.junit.AfterClass;
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.api.datastore.Query.FilterOperator;
import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
import com.google.appengine.tools.development.testing.LocalServiceTestHelper;
import com.google.code.twig.annotation.AnnotationObjectDatastore;
public class AgentContrTest {
private static final Logger log = Logger.getLogger("AgentContrTest.class");
private static UserController uc;
private static GameController gc;
private static AgentController ac;
private static final LocalServiceTestHelper helper =
new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig());
private AnnotationObjectDatastore datastore = new AnnotationObjectDatastore(false);
@BeforeClass
public static void setUpOnce() {
gc = GameController.getInstance();
uc = UserController.getInstance();
ac = AgentController.getInstance();
}
@Before
public void setUp() {
helper.setUp();
try {
uc.register("userForTest", "test", "test@gmail.de", false);
}
catch (NameExistsException ne) {
}
catch (EmailFormatException ee) {
}
}
@After
public void tearDown() {
helper.tearDown();
}
// Testing the raising of NameExistsException in createAgent(String name, String url, String owner)
@Test(expected=NameExistsException.class)
public void testCreateAgentExc1() throws NameExistsException {
Agent ag1 = ac.createAgent("Agent1", "www.agent1.com", "Owner1");
Agent ag2 = ac.createAgent("Agent1", "www.agent2.com", "Owner2");
}
// Testing getAgents()
@Test
public void testGetAgents1() throws NameExistsException {
datastore.disassociateAll();
ArrayList<Agent> agents1 = ac.getAgents();
ac.createAgent("Agent1", "www.agent1.com", "Owner1");
ac.createAgent("Agent2", "www.agent2.com", "Owner2");
ac.createAgent("Agent3", "www.agent3.com", "userForTest");
ArrayList<Agent> agents2 = ac.getAgents();
assertTrue(agents1.size()==0);
assertTrue(agents2.size()==3);
datastore.disassociateAll();
}
// Testing getAgents(String user)
@Test
public void testGetAgents2() throws NameExistsException {
ArrayList<Agent> agents = ac.getAgents();
assertTrue(agents.size()==0);
datastore.disassociateAll();
ac.createAgent("Agent1", "www.agent1.com", "Owner1");
ac.createAgent("Agent2", "www.agent2.com", "Owner2");
ac.createAgent("Agent3", "www.agent3.com", "userForTest");
ArrayList<Agent> agents2 = ac.getAgents("userForTest");
assertTrue(agents2.size()==1);
}
These are the functions in my AgentController that I am testing:
public ArrayList<Agent> getAgents(String user) {
ArrayList<Agent> agents = new ArrayList<Agent>();
Iterator<Agent> agentIterator = datastore.find().type(Agent.class)
.addFilter("owner", FilterOperator.EQUAL, user)
.now();
while (agentIterator.hasNext()) {
agents.add(agentIterator.next());
}
return agents;
}
public Agent createAgent(String name, String url, String owner) throws NameExistsException {
Agent agent = datastore.load(Agent.class, name);
if (agent != null)
throw new NameExistsException();
agent = new Agent();
agent.setName(name);
agent.setUrl(url);
agent.setOwner(owner);
datastore.store(agent);
return agent;
}
The testCreateAgentExc1 is working just fine. But the testGetAgents2() is throwing a NameExistsException, which it should not do. If i rename the agents in this test to ‘Agent4’ to ‘Agent6’ it is working just fine.
Due to ‘http://code.google.com/intl/de-DE/appengine/docs/java/tools/localunittesting.html‘
the Datastore should delete all data between the tests, so the NameExistsException should not be raised.
You are not resetting your
datastoreobject between tests. I’m not sure how twig works, but it (or its configuration) is the cause of the leak.