3

免責事項 - Android アプリ内から sqlite db を作成および管理するために、GreenDAO ORM を使用しました。

私のAndroidアプリでは、単体テストを作成しているときに、テストが実際のデータベースを汚染しないようにするために、通常のデータベースとは異なる特定のデータベースを使用するようにアプリに切り替えるように指示したいと考えています。それに応じて、適切な関数を使用して新しいデータベースを作成し、このように切り替えました

public class DbTests extends ApplicationTestCase<MyApp> {
private static final String TAG = "DbTests";
private MyApp mApplication;
private Context mContext;

public DbTests() {
    super(MyApp.class);
}

@Override
protected void setUp() throws Exception {
    Log.d(TAG, "in setUp");
    super.setUp();
    createApplication();
    mApplication = getApplication();
    Log.d(TAG, "setUp done");
}

@Override
public void tearDown() throws Exception {
    super.tearDown();
}


private void setUpFreshInstallNoDataCase(boolean val) {
    assertNotNull(mApplication);
    LocalDataHelpers.setupLocalData(mApplication, InitialConditions.FreshInstallNoData);
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public void testFreshInstallNoDataCase() {
    Log.d(TAG, "testFreshInstallNoDataCase");
    setUpFreshInstallNoDataCase(true);

    mContext = mApplication.getApplicationContext();
    assertEquals(0, PersonRepository.getAllPersons(mContext).size());
}
}



public class LocalDataHelpers {
public static final String TAG = "LocalDataHelpers";

static MyApp globalApplication;

public static void setupLocalData(MyApp app, String condition) {
    globalApplication = app;
    if(globalApplication.daoSession != null){
        Log.d(TAG, "daoSession not null");
        globalApplication.daoSession.clear();
        globalApplication.setupDatabase(condition);     
    }
}
}

私のアプリケーションでは、onCreate と setupDatabase は次のようになっています

public void onCreate() {
    Log.d(TAG, "onCreate");
    super.onCreate();
    EventBus.getDefault().register(this);
    EventBus.getDefault().post(new PersonEvents.FetchPersonsFromServer());
    setupDatabase(InitialConditions.DefaultSetUp);
}

private void setupDatabase(String condition) {
    DaoMaster.DevOpenHelper helper = null;
    SQLiteDatabase db = null;
    DaoMaster daoMaster = null;
    if (condition.equals(InitialConditions.DefaultSetUp)) {
        helper = new DaoMaster.DevOpenHelper(this, "example-db", null);
        db = helper.getWritableDatabase();
        daoMaster = new DaoMaster(db);
    }
    else if (condition.equals(InitialConditions.FreshInstallNoData)) {
        helper = new DaoMaster.DevOpenHelper(this, "freshInstallNoData-db", null);
        db = helper.getWritableDatabase();
        daoMaster = new DaoMaster(db);
        //clear all possible data here by dropping all tables and recreate
        Log.d(TAG, "Dropping all tables and recreating them");
        DaoMaster.dropAllTables(db, true);
        DaoMaster.createAllTables(db, false);
    }
    if (helper != null && db != null && daoMaster != null) {
        daoSession.clear();
        daoSession = daoMaster.newSession();
    }
    else {
        Log.e(TAG, "setupDatabase Error : condition " + condition + ", either helper or db or daomaster is null");
    }
    List<Pair<String, String>> dbs = getDaoSession().getDatabase().getAttachedDbs();
    for (Pair<String, String> pair : dbs) {
        Log.d(TAG, "setupDatabase <" + pair.first + ", " + pair.second + ">");
    }
}

FetchPersonsFromServer の onEvent は、人のリストを取得し、PersonDao を使用してデータベースに保存します。

ここで、デバイスからすべてのアプリ データを消去してテストを直接実行すると、期待どおりにテストに合格します。ただし、アプリを通常どおり実行してからテストを実行すると、assert ステートメントが失敗します。

assertEquals(0, PersonRepository.getAllPersons(mContext).size());

サイズはデフォルトの db 値と同じです。

私はその理由を理解しようとして夢中になっています。setupDatabase のログ ステートメントは、正しいデータベース名、つまり freshdbinstall-db が表示されていることを示しています...

Androidでは2つのデータベースは許可されていませんか? 論理的に問題はないはずですか?それを許さないのはGreenDaoですか?何か基本的なミスをしているのでしょうか...

助けてください。


編集: greenDao android ORM ライブラリを使用して複数の *.db ファイルを作成していますか?

更新 1

adb shell、run-as cat /sdcard/debug/db、および adb pull を使用して、テストの失敗後にデフォルト データベースと新しいデータベースの両方を調べました。

新しいデータベースは期待どおりで、Person エントリはなく、デフォルトでは 10 エントリです。したがって、問題は assert/query 呼び出しにあると思います...何らかの理由でデフォルトのデータベースを使用しているようです...

public static List<Person> getAllPersons(Context context) {
    return getPersonDao(context).loadAll();
}

private static PersonDao getPersonDao(Context c) {
    return ((MyApp) c.getApplicationContext()).getDaoSession().getPersonDao();
}

これによると、セッションが更新されておらず、前のセッションがまだ使用されているようです

4

1 に答える 1