用于测试和实际使用的Android应用程序不同的SQLite数据库 [英] Different sqlite databases for testing and actual use in android app
问题描述
免责声明 - 我用GreenDAO ORM创建和从我的Android应用程序中管理sqlite的分贝
Disclaimer - I have used GreenDAO ORM for creating and managing the sqlite db from within my android app.
有关我的Android应用程序,同时编写单元测试,我想告诉应用程序切换到使用一定分贝这与通常不同,以确保该测试没有污染的真正分贝。与此相对应我使用了适当的函数来创建新的数据库,并切换到像这样
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.
这篇关于用于测试和实际使用的Android应用程序不同的SQLite数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!