Acceptance testing of preloading data in the GAE dev server data warehouse

In my application, I have a set of DAOs that I insert into my application layer. For the acceptance test I'm writing, I want to preload the dev_server repository data with the data, so I use the same Spring configuration in my JUnit test (using the @ContextConfiguration annotation) to insert an instance of the corresponding DAO into my test, When I actually I'm going to store some data, for example:

dao.add(entity) 

I get the terrible "No API environment for this stream."

 Caused by: java.lang.NullPointerException: No API environment is registered for this thread. at com.google.appengine.api.datastore.DatastoreApiHelper.getCurrentAppId(DatastoreApiHelper.java:108) at com.google.appengine.api.datastore.DatastoreApiHelper.getCurrentAppIdNamespace(DatastoreApiHelper.java:118) .... 

This is probably due to the fact that my test case was not read in the GAE-web.xml application with the details of the application (although I assume that I am really mistaken here); therefore, he does not know to write to the same data file that the application running on dev_server reads / writes.

How can I make my test “point” to the same data file as the application? Is there some kind of “data source” mechanism that I can introduce both into the application and into the test? Is there a way to get my test to force the datastore api to read the necessary configuration?

+4
source share
3 answers

I found a solution !!!!

For some reason, the Namespace, AppID, and AuthDomain fields of the test data warehouse must match the dev_server fields, then dev_server can see the objects inserted into the test.

You can see the values ​​for the environment (dev_server or test code) with the following statements

 System.out.println(NamespaceManager.get()); System.out.println(ApiProxy.getCurrentEnvironment().getAppId()); System.out.println(ApiProxy.getCurrentEnvironment().getAuthDomain()); 

In your case, LocalServiceTestHelper (ex: gaeHelper) you can set the values ​​for the test environment

 // the NamespaceManager is thread local. NamespaceManager.set(NamespaceManager.getGoogleAppsNamespace()); gaeHelper.setEnvAppId(<the name of your app in appengine-web.xml>); gaeHelper.setEnvAuthDomain("gmail.com"); 

Then dev_server will see your entities. However, due to synchronization problems, if the test is written to the data warehouse after running dev_server, dev_server will not see it if it cannot be forced to re-read the file (which I still do not understand). In addition, the server must be restarted.

0
source

Here is a page that talks about how to run unit tests that connect to the dev datastore. Is this what you are looking for? This basically speaks of two classes: LocalServiceTestHelper and LocalDatastoreServiceTestConfig, which you can use to set up the environment for testing. As long as the above example applies to unit tests, I believe that it will also work for your situation.

Then you can configure things such that the datastore file is written to disk or simply stored in memory (for faster tests). If you want this data to go to the same place as your dev server, you probably want to adjust it, since I think the default option is “in memory”. If you look at javadoc , there is a setBackingStoreLocation method where you can specify any file you want.

+3
source

I found a workaround, although this is not very pleasant, because each testing method does not clear the data store, as explained in the Local Unit Testing for Java article, however, the Datastore starts to clear every time the Test class is launched, so this is not so bad if you are careful about this.

The problem is that when using SpringJUnit4ClassRunner spring environment is created before the @Before annotation, the solution uses @BeforeClass and uses the static variable for LocalServiceTestHelper to have the spring created before the creation.

 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:META-INF/spring/context-test.xml") @Transactional public class MyTest { @Inject private MyService myService; private static final LocalServiceTestHelper helper = new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig()); @BeforeClass public static void beforeClass() { helper.setUp(); } @AfterClass public static void afterClass() { helper.tearDown(); } 

If anyone has a better solution, I will be happy to hear!

0
source

Source: https://habr.com/ru/post/1336578/


All Articles