用于测试和实际使用的Andr​​oid应用程序不同的SQLite数据库 [英] Different sqlite databases for testing and actual use in android app

查看:300
本文介绍了用于测试和实际使用的Andr​​oid应用程序不同的SQLite数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

免责声明 - 我用GreenDAO ORM创建和从我的Andr​​oid应用程序中管理sqlite的分贝

Disclaimer - I have used GreenDAO ORM for creating and managing the sqlite db from within my android app.

有关我的Andr​​oid应用程序,同时编写单元测试,我想告诉应用程序切换到使用一定分贝这与通常不同,以确保该测试没有污染的真正分贝。与此相对应我使用了适当的函数来创建新的数据库,并切换到像这样

For my android app, while writing unit tests, I wish to tell the app to switch to using a certain db which is different from the normal one in order to make sure that the tests do not contaminate the real db. Correspondingly I have used appropriate functions to create new db and switch to it like this

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都是这样

In my application onCreate and setupDatabase are like this

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的数据库。

The onEvent for FetchPersonsFromServer gets a list of persons and saves them to the db using PersonDao.

现在如果我从我的设备清除所有的应用数据和直接运行测试,如预期测试通过​​。但是,如果我正常运行应用程序,然后运行测试,断言语句在

Now If I clear all app data from my device and run the test directly, as expected the test passes. However if I run the app normally, and then run tests, the assert statement fails at

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

与尺寸与默认分贝值的

with the size as that of the default db value.

我要疯了试图找出原因。在setupDatabase日志报表显示正确的数据库名称显示出来,即freshdbinstall-DB ...

I am going crazy trying to figure out why. The log statements in setupDatabase show that the correct db name is showing up ie freshdbinstall-db...

两个DBS不是在Android的允许?逻辑上应该没有问题?它是GreenDao不允许呢?我在做一些基本的错误...

Are two dbs not allowed in android? Logically there should be no issues? Is it GreenDao which doesn't allow it? Am I making some basic mistakes...

请帮忙。

编辑:为<一个href=\"http://stackoverflow.com/questions/23196543/creating-more-than-1-db-file-with-greendao-android-orm-library\">Creating超过1 *与greenDao Android的ORM库.db文件甚至隐约有关?

Edit : Is Creating more than 1 *.db file with greenDao android ORM library even vaguely relevant?

我已经使用亚行外壳,运行如猫/ SD卡/调试/ db和亚行拉来看看这两个测试失败后的默认和新鲜的数据库

I have used adb shell, run-as cat /sdcard/debug/db and adb pull to look at both the default and fresh databases after the test failure

新鲜的数据库是没有人的条目,并在默认的10项预期。所以我想问题出在断言/查询电话...这似乎是使用默认的数据库出于某种原因......望着库code这是

The fresh database is as expected with no Person entries and 10 entries in default. So I guess the problem lies in the assert/query call... It seems to be using the default db for some reason... Looking at repository code which is

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

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

根据这似乎是会话没有被更新,previous一个仍在使用

As per this seems like session is not being updated and the previous one is still being used

推荐答案

如果 Robolectric 是一个选择,这是我们如何使用带有填充测试数据在内存中的SQLite数据库:

If Robolectric is an option for you, this is how we use an in-memory SQLite database with populated test data:

TestApplication.java

public class TestApplication extends YourApplication
    implements TestLifecycleApplication {

    @Override
    public void onCreate() {
        super.onCreate();
        YourProvider provider = new YourProvider(YOUR_CONTENT_AUTHORITY);
        provider.onCreate();
        ShadowContentResolver.registerProvider(YOUR_CONTENT_AUTHORITY, provider);
    }
    ...
}

SomeTest.java

@RunWith(RobolectricTestRunner.class)
public class SomeTest {
    @Test
    public void testSQLite() {
        // insert test data into in-memory SQLite
        ShadowContentResolver resolver = shadowOf(Robolectric.getShadowApplication().getContentResolver());
        ContentValues cv = new ContentValues();
        cv.put("column_name", "column_value");
        resolver.insert(YOUR_CONTENT_URI, cv);
        // test against in-memory SQLite
        ...
    }
    ...
}

对不起,我忘了文章,我读这篇文章的来源。

Sorry I forget the source of article where I read this.

这篇关于用于测试和实际使用的Andr​​oid应用程序不同的SQLite数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆