在测试我的DB时,我得到以下错误:
显然取决于我测试的设备。当我运行这个应用程序时,错误不会发生。不过,如果我不能测试这个应用程序,我的代码可能有问题。
该应用程序使用了两个库,这两个库应该与SQLDelight和SQLBrite很好地结合在一起,这可能会使这个问题变得更加具体。
为了更好地理解正在发生的事情,我将简要描述我的数据包中的文件。
-+-data-+
| |-manager-+
| | |-LocationManager
| | |-RunManager
| |-model-+
| | |-Location
| | |-Run
|-DatabaseContract
|-DataRepository
|-MyDBHelperLocation和Run文件是由SQLDelight生成的行模型。LocationManager和RunManager使生成sqlStatements能够从相应的表中插入或删除数据。在RunManager下面,LocationMangager看起来类似。
public class RunManager {
public final Run.InsertRun insertRace;
public final Run.DeleteRun deleteRun;
public final Run.DeleteRunWhereTimeSmallerThan deleteRunWhereTimeSmallerThan;
public RunManager(SQLiteDatabase db) {
insertRace = new Run.InsertRun(db);
deleteRun = new Run.DeleteRun(db);
deleteRunWhereTimeSmallerThan = new Run.DeleteRunWhereTimeSmallerThan(db);
}
}MyDBHelper以标准的方式扩展了SQLiteOpenHelper。
public class MyDbHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "runner.db";
private static MyDbHelper INSTANCE = null;
private MyDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public static MyDbHelper getInstance(Context context) {
if (INSTANCE == null) {
INSTANCE = new MyDbHelper(context);
}
return INSTANCE;
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
// create table (omitted)
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
// upgrade table (omitted)
}
}数据存储库聚合各种插入和查询操作。
public class DataRepository implements DatabaseContract {
private static DataRepository INSTANCE = null;
BriteDatabase briteDatabase;
LocationManger locationManger;
RunManager runManager;
private DataRepository(Context context) {
SqlBrite sqlBrite = new SqlBrite.Builder().build();
MyDbHelper helper = MyDbHelper.getInstance(context);
briteDatabase = sqlBrite.wrapDatabaseHelper(helper, Schedulers.io());
locationManger = new LocationManger(briteDatabase.getWritableDatabase());
runManager = new RunManager(briteDatabase.getWritableDatabase());
}
public static DataRepository getInstance(Context context) {
if (null == INSTANCE) {
INSTANCE = new DataRepository(context);
}
return INSTANCE;
}
@Override
public Observable<List<Run>> getAllRun() {
return briteDatabase.createQuery(
Run.TABLE_NAME,
Run.SELECT_ALL
).mapToList(Run.MAPPER::map);
}
@Override
public Observable<List<Location>> getLocationsForRun(long id) {
return briteDatabase.createQuery(
Location.TABLE_NAME, Location.FACTORY.selectAllByRace(id).statement
).mapToList(Location.MAPPER::map);
}
@Override
public long insertRun(double distance, long duration, double avgSpeed, long timestamp) {
runManager.insertRace.bind(distance, duration, avgSpeed, timestamp);
return briteDatabase.executeInsert(Run.TABLE_NAME, runManager.insertRace.program);
}
@Override
public void deleteRun(long id) {
runManager.deleteRun.bind(id);
briteDatabase.executeUpdateDelete(Run.TABLE_NAME, runManager.deleteRun.program);
}
@Override
public void deleteRunWhereTimestampSmallerThan(long timestamp) {
runManager.deleteRunWhereTimeSmallerThan.bind(timestamp);
briteDatabase.executeUpdateDelete(Run.TABLE_NAME, runManager.deleteRunWhereTimeSmallerThan.program);
}
@Override
public long insertLocation(long raceId, double lat, double lng, double alt, long timestamp) {
locationManger.insertLocation.bind(raceId, lat, lng, alt, timestamp);
return briteDatabase.executeInsert(Location.TABLE_NAME, locationManger.insertLocation.program);
}
public Observable<List<SingleRun>> getAllSingleRunModels() {
return briteDatabase.createQuery(
Run.TABLE_NAME,
Run.SELECT_ALL
).mapToList(Run.MAPPER::map)
// omitted
}现在是问题的主要部分。现在,我编写了以下测试用例,并遇到了顶部列出的错误。有趣的是,当我单独运行测试时,没有任何错误,所有的测试都通过了。
@RunWith(AndroidJUnit4.class)
@LargeTest
public class DataRepositoryTest {
private Context context;
private DataRepository mDataRepository;
@Before
public void setUp() {
context = InstrumentationRegistry.getTargetContext();
context.deleteDatabase(MyDbHelper.DATABASE_NAME);
mDataRepository = DataRepository.getInstance(InstrumentationRegistry.getTargetContext());
}
@Test
public void testPreConditions() {
Assert.assertNotNull(context);
Assert.assertNotNull(mDataRepository);
}
@Test
public void testInsertRace() { // this test failes when all tests are run.
long raceID1 = mDataRepository.insertRun(5.0, 35, 3.5, 1000);
Assert.assertEquals(1, raceID1);
long raceID2 = mDataRepository.insertRun(10.0, 70, 3.5, 2000);
Assert.assertEquals(2, raceID2);
long locationID1 = mDataRepository.insertLocation(raceID1, 0.5, 0.5, 0, 1000);
Assert.assertEquals(1, locationID1);
long locationID2 = mDataRepository.insertLocation(raceID1, 0.5, 0.5, 0, 1001);
Assert.assertEquals(2, locationID2);
long locationID3 = mDataRepository.insertLocation(raceID1, 0.5, 0.5, 0, 1002);
Assert.assertEquals(3, locationID3);
long locationID4 = mDataRepository.insertLocation(raceID1, 0.5, 0.5, 0, 1003);
Assert.assertEquals(4, locationID4);
long locationID5 = mDataRepository.insertLocation(raceID2, 0.5, 0.5, 0, 2000);
Assert.assertEquals(5, locationID5);
long locationID6 = mDataRepository.insertLocation(raceID2, 0.5, 0.5, 0, 2001);
Assert.assertEquals(6, locationID6);
long locationID7 = mDataRepository.insertLocation(raceID2, 0.5, 0.5, 0, 2002);
Assert.assertEquals(7, locationID7);
long locationID8 = mDataRepository.insertLocation(raceID2, 0.5, 0.5, 0, 2003);
Assert.assertEquals(8, locationID8);
}
@Test
public void testRaceObservable() {
long raceID1 = mDataRepository.insertRun(5.0, 35, 3.5, 1000);
Run run1 = Run.FACTORY.creator.create(raceID1, 5.0, 35l, 3.5, 1000l);
Assert.assertEquals(1, raceID1);
long raceID2 = mDataRepository.insertRun(10.0, 70, 3.5, 2000);
Run run2 = Run.FACTORY.creator.create(raceID2, 10.0, 70l, 3.5, 2000l);
Assert.assertEquals(2, raceID2);
List<Run> expectedResult = Arrays.asList(run1, run2);
Assert.assertEquals(expectedResult, mDataRepository.getAllRun().blockingFirst());
}
}我假设这与从不同线程访问DB有关,但我不知道如何解决这个问题。
发布于 2017-09-20 14:06:53
您的问题是,当setUp第二次运行时,DataRepository.getInstance返回旧的数据存储库,这意味着它不会创建新的SQLiteOpenHelper。当您删除数据库时,您还需要为DataRepository和MyDbHelper清理您的单身者。
或者,根本不要使用单数:
@Before
public void setUp() {
context = InstrumentationRegistry.getTargetContext();
context.deleteDatabase(MyDbHelper.DATABASE_NAME);
mDataRepository = new DataRepository(InstrumentationRegistry.getTargetContext());
}
// In DataRepository.java
DataRepository(Context context) {
SqlBrite sqlBrite = new SqlBrite.Builder().build();
MyDbHelper helper = new MyDbHelper(context);
briteDatabase = sqlBrite.wrapDatabaseHelper(helper, Schedulers.io());
locationManger = new LocationManger(briteDatabase.getWritableDatabase());
runManager = new RunManager(briteDatabase.getWritableDatabase());
}
// In MyDbHelper.java
MyDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}https://stackoverflow.com/questions/46323033
复制相似问题