androidjunit4proto-datastore

Testing ProtoDatastore with JUnit4


I have a repository class that works with a Proto DataStore I have defined that is NOT the Preference DataStore equivalent. My proto file looks something like this:

syntax = "proto3";

option java_package = "PACKAGE_NAME";
option java_multiple_files = true;

message SomeItem {
  string itemId = 1;
  string itemDescription = 2;
}

message ListOfItems {
  repeated SomeItem items = 1;
}

Inside my application, I instantiate the Proto DataStore using the Global context object like so:

private val Context.someItemsStore: DataStore<ListOfItems> by dataStore(
    fileName = DATA_STORE_FILE_NAME,
    serializer = SerializerClass,
)

What I don't understand is how I can test my datastore without mocking it. I.E. seeing actual values being set/removed/etc.

I have read this article which shows how to do just that with the Preference DataStore and vaguely hints that the same can be done with Proto DataStore.

The problem is the following logic inside of a test class:

private val testDataStore: DataStore<Preferences> =
    PreferenceDataStoreFactory.create(
        scope = testCoroutineScope,
        produceFile = { testContext.preferencesDataStoreFile(TEST_DATASTORE_NAME) }
    )

Above is a snippet of logic to instantiate the Preference DataStore, but I could not find the equivalent logic for instantiating a Proto DataStore inside of a test class. I have also seen this SO question using RoboElectric.

Should I be instantiating my Proto DataStore in my test the same way I am doing it inside of the application? If that is so, when I tried doing that, I had to grab the application context using ApplicationProvider.getApplicationContext(), but that doesn't have a reference to the datastore on it (unlike inside the application itself).

Any idea how this can be done?


Solution

  • After searching online and tinkering with things I found a viable solution. So, I am putting it here for posterity's sake.

    To create the DataStore, you can use the DataStoreFactory.create, which does not rely on the Application Context. Instead you need to pass in a coroutine scope, which you can create with TestCoroutineScope.

    DataStoreFactory.create(
                scope = testCoroutineScope,
                produceFile = {
                    //Create datastore file here
                },
                serializer = //Your serializer here
            )