2014-01-05 3 views
3

Я очень новичок в Robolectric, поэтому извиняюсь заранее, если мне не хватает чего-то очевидного здесь. У меня есть приложение, которое загружает базу данных из каталога assets с использованием SQLiteAssetHelper, и я бы хотел протестировать эту базу данных, используя структуру Robolectric. Я могу получить ссылку на базу данных, но она кажется пустой. SQLiteAssetHelper выводит сообщение «успешно открытая база данных» в журнал, но в базе данных нет таблиц.Использование Robolectric с SQLiteAssetHelper

Edit: Вот код, я использую, чтобы получить базу данных в моем setUp метод с использованием класса @ user2953017 размещены ниже:

@Before 
public void setUp() { 
    Context context = Robolectric.getShadowApplication().getApplicationContext(); 
    SQLiteDatabase db = (new DataBaseWrapper(context)).getReadableDatabase(); 

    Cursor c = db.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null); 
    if (!c.moveToFirst()) { 
     Log.w("debug", "No tables!"); 
    } 

    // My second query here fails, since the database contains no tables. 
} 

От LogCat:

W/debug: No tables! 
DEBUG: Loading resources for android from jar:/home/<name>/.m2/repository/org/robolectric/android-res/4.1.2_r1_rc/android-res-4.1.2_r1_rc-real.jar!/res... 
E/Debug: java.lang.RuntimeException: SQL exception in query 

причиной исключения SQL является то, что имя таблицы, указанное в запросе, не найдено.

Буду благодарен за любые советы.

ответ

2

Сначала скопируйте свою базу данных из папки ресурсов в папку базы данных приложения. Вот код, который будет копировать базу данных

public class DataBaseWrapper extends SQLiteOpenHelper 
{ 
    private static String TAG = DataBaseWrapper.class.getName(); 
    private String DB_PATH; //= "/data/data/com.example.yourproject/databases/"; 
    private static String DB_NAME = "Database.sqlite"; 
    private SQLiteDatabase myDataBase = null; 
    private final Context myContext; 

    public DataBaseWrapper(Context context) 
    { 
    super(context, DB_NAME, null, 1); 

     this.myContext = context; 
     DB_PATH="/data/data/" + context.getPackageName() + "/" + "databases/"; 
     Log.v("log_tag", "DBPath: " + DB_PATH); 
    // File f=getDatabasePath(DB_NAME); 
    } 

    public void createDataBase() throws IOException{ 
    boolean dbExist = checkDataBase(); 
    if(dbExist){ 
    Log.v("log_tag", "database does exist"); 
    }else{ 
    Log.v("log_tag", "database does not exist"); 
    this.getReadableDatabase(); 
    try { 
     copyDataBase(); 
     } catch (IOException e) { 
     throw new Error("Error copying database"); 
     } 
    } 
    } 

    private void copyDataBase() throws IOException{ 
    InputStream myInput = myContext.getAssets().open(DB_NAME); 
    String outFileName = DB_PATH + DB_NAME; 
    OutputStream myOutput = new FileOutputStream(outFileName); 
    byte[] buffer = new byte[1024]; 
    int length; 
    while ((length = myInput.read(buffer))>0){ 
    myOutput.write(buffer, 0, length); 
    } 
    myOutput.flush(); 
    myOutput.close(); 
    myInput.close(); 
    } 

    private boolean checkDataBase(){ 

    File dbFile = new File(DB_PATH + DB_NAME); 
    //Log.v("dbFile", dbFile + " "+ dbFile.exists()); 
    return dbFile.exists(); 

} 

public boolean openDataBase() throws SQLException 
{ 
    String mPath = DB_PATH + DB_NAME; 
    //Log.v("mPath", mPath); 
    myDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.CREATE_IF_NECESSARY); 
    //mDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS); 
    return myDataBase != null; 

} 


    @Override 
    public synchronized void close() 
    { 
    if(myDataBase != null) 
     myDataBase.close(); 
    super.close(); 
    } 

@Override 
public void onCreate(SQLiteDatabase db) 
{ 


    } 

@Override 
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
{ 
    Log.v(TAG, "Upgrading database, this will drop database and recreate."); 
    } 
    } 

Также ЧК эту ссылку .. это может быть полезно для и Testing SQLite database in Robolectric

Попробуйте эти вещи:

1.Delete вашу базу данных от терминала

adb shell 
cd /data/data/com.example.apploicationname/databases 
rm * 

и снова заново установите приложение на эмулятор.

  1. Попытайтесь увеличить ОЗУ эмулятора. Такая же ошибка пришла ко мне, несмотря на все мои данные в базе данных, но когда я увеличил ОЗУ эмулятора с 1024 до 2000 .. Это сработало.

  2. Скопируйте базу данных из DDMS в системную файловую систему и откройте ее через браузер sqlite и проверьте, существует ли таблица. Ссылка для SQLite браузера http://sourceforge.net/projects/sqlitebrowser/files/sqlitebrowser/

+2

Большое спасибо за вашу помощь. Я получаю исключение «FileNotFound» из конструктора 'FileOutputStream' в' copyDataBase() '. 'outFileName' установлен в'/data/data//databases/ '. Любая идея, что здесь происходит не так? – Ben

+0

Вы пишете этот файл на SD-карте? Если да, то добавьте эту строку в manifest.xml: .. и не пытайтесь использовать свой путь DB_PATH + DB_NAME –

+0

Я просто использую внутреннее хранилище, и я получаю 'outFileName' из' DB_PATH + DB_NAME'. Спасибо за вашу помощь. Я обновлю этот вопрос, если мне удастся заставить это работать, когда у меня будет время снова заглянуть в него. – Ben

Смежные вопросы