Search code examples
javagoogle-cloud-platformgoogle-cloud-datastoreobjectify

Objectify Unit Tests are persisting data to Google Cloud Datastore


I have a Unit Test that attempts to follow the Unit Test instructions found here. I find that any entities that I persist are actually stored in the "real" Google Cloud Platform DataStore associated with my Google Project.

My intention was that the Entities would be persisted to In Memory storage and torn down after each test.

When the test runs it appears that it tries to write to the Local Datastore, but everything somehow ends up being written to the Cloud Datastore. Here's the console output

com.google.appengine.api.datastore.dev.LocalDatastoreService init INFO: Local Datastore initialized: Type: High Replication Storage: In-memory Jan 09, 2019 10:44:49 AM com.google.appengine.api.datastore.dev.LocalDatastoreService init INFO: Local Datastore initialized: Type: High Replication Storage: In-memory

Here's my Unit Test

public class AccountGCPDatastoreDaoTest {

private final LocalServiceTestHelper helper = new LocalServiceTestHelper(
            new LocalDatastoreServiceTestConfig().setApplyAllHighRepJobPolicy());

private Closeable session;

private AccountGCPDatastoreDao dao = new AccountGCPDatastoreDao();

@BeforeClass
public static void setUpBeforeClass() {
    System.out.println("init Objectify");
    ObjectifyService.init(new ObjectifyFactory());
    ObjectifyService.register(Account.class);
}

@Before
public void setUp() { ;
    helper.setUp();
    session = ObjectifyService.begin();
}

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


@Test
public void save() {
    Account account = new Account(1L, "Test Account", false, AccountType.SMALL);
    dao.save(account);

    Account retAcc = ofy().load().type(Account.class).id(1).now();
    assertEquals(new Long(1),retAcc.getId());
    assertEquals("Test Account",retAcc.getName());
    assertFalse(retAcc.getPaidSubscription());
    assertEquals(AccountType.SMALL,retAcc.getAccountType());
}


@Test
public void findAccountsForRegistration_NoAccountsExist() {

    List<Account> accountsForRegistration = dao.findAccountsForRegistration();
    assertEquals(0,accountsForRegistration.size());


}

My Account entity :

@Entity
public class Account {

@Id private Long id;
private String name;
private boolean paidSubscription;
@Index private AccountType accountType;

private Account(){}

public Account(Long id,
               String name,
               boolean paidSubscription,
               AccountType accountType){
    this.id = id;
    this.name = name;
    this.paidSubscription = paidSubscription;
    this.accountType = accountType;
}

public Long getId() {
    return id;
}

public String getName() {
    return name;
}

public AccountType getAccountType(){
    return accountType;
}

public boolean getPaidSubscription() {
    return paidSubscription;
}

}


Solution

  • It looks like you're using Objectify6, which uses the new dedicated datastore API, but you're looking at documentation for the old appengine-everything-combined API.

    The new datastore API has a completely different emulator. That local test harness you're using is what you would use with Objectify5 or what used to be called the "appengine datastore low level API".

    The documentation for setting up a test environment for the new API wasn't great the last time I looked. I recommend looking at Objectify's test harness itself. You can actually use the Objectify JUnit5 interceptors directly if you want to upgrade from JUnit4. Otherwise it shouldn't be too hard to figure out what's going on.

    Here's the meat of it:

    https://github.com/objectify/objectify/blob/master/src/test/java/com/googlecode/objectify/test/util/LocalDatastoreExtension.java https://github.com/objectify/objectify/blob/master/src/test/java/com/googlecode/objectify/test/util/ObjectifyExtension.java