/******************************************************************************* * Copyright 2011 Android Test and Evaluation Club * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package jp.group.android.atec.sf.unit; import java.lang.reflect.Method; import jp.group.android.atec.sf.data.ColumnInfo; import jp.group.android.atec.sf.importer.FileType; import jp.group.android.atec.sf.importer.SQLiteImportFactory; import jp.group.android.atec.sf.importer.SQLiteImporter; import jp.group.android.atec.sf.util.SQLiteMetaLoader; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.test.AndroidTestCase; import android.test.RenamingDelegatingContext; /** * データベースを利用したテストを行うための基底テストケースクラスです。 * * @author ussy */ public abstract class DatabaseTestCase extends AndroidTestCase { private SQLiteDatabase db; /** * @return {@link #createSQLiteOpenHelper()} で生成した {@link SQLiteDatabase} */ protected SQLiteDatabase getSQLiteDatabase() { return db; } private Context context; /** * {@link #createDatabaseContext()} で生成した {@link Context} を取得します。 * * <p> * デフォルトでは {@link #getContext()} で取得したコンテキストを {@link RenamingDelegatingContext} でラップしたものを取得します。 * </p> * * @return データベースに使用するテスト用コンテキスト */ protected Context getDatabaseContext() { return context; } /** * データベースに使用するコンテキストを生成します。 * * デフォルトでは {@link RenamingDelegatingContext} を使用して、元のデータベースには影響を与えないようにします。 * * @return {@link RenamingDelegatingContext} */ protected Context createDatabaseContext() { return new RenamingDelegatingContext(getContext(), "test_"); } /** * データベースのテストに使用する {@link SQLiteOpenHelper} を生成します。 * * {@link #getDatabaseContext()} を利用して、 {@link SQLiteOpenHelper} を生成してください。 * * @return {@link SQLiteDatabase} */ protected abstract SQLiteOpenHelper createSQLiteOpenHelper(); /** * テストプロジェクトのコンテキストを取得します。 * * <p> * テストプロジェクトのリソースにアクセスしたい場合に利用します。 * </p> * * @return テストプロジェクトのコンテキスト */ protected Context getTestProjectContext() { try { // テスト用コンテキストを取得する方法がないため、リフレクションで取得 Method method = getClass().getMethod("getTestContext"); return (Context) method.invoke(this); } catch (Exception e) { throw new RuntimeException(e); } } /** * データベースから指定したテーブルのカラム情報を取得します。 * * @param table * テーブル名 * @return カラム情報 */ public ColumnInfo[] loadColumnInfos(String table) { return new SQLiteMetaLoader(db).load(table); } /** * データベースを切り替えます。 * * <p> * バージョンが違う {@link SQLiteOpenHelper} を指定した場合は、アップグレード処理が実行されます。 * </p> * * @param helper * {@link SQLiteOpenHelper} */ public void replaceSQLiteOpenHelper(SQLiteOpenHelper helper) { if (db.isOpen()) { db.close(); } db = helper.getWritableDatabase(); } /** * 指定したファイル種別、パスから SQLite にデータをインポートします。 * * <p> * テストデータは UTF-8 で記述されていることを想定します。 * </p> * * @param t * インポートするデータ種別 * @param path * インポートするパス */ protected void importData(FileType t, String path) { importData(t, path, "utf-8"); } /** * 指定した種別、パスから SQLite にデータをインポートします。 * * @param t * インポートするデータ種別 * @param path * インポートする パス * @param charset * インポートするファイルの文字コード */ protected void importData(FileType t, String path, String charset) { SQLiteImportFactory factory = new SQLiteImportFactory(getTestProjectContext()); SQLiteImporter importer = factory.create(t, charset); importer.importData(path, db); } /** * {@inheritDoc} */ @Override public void runBare() throws Throwable { context = createDatabaseContext(); SQLiteOpenHelper helper = createSQLiteOpenHelper(); if (helper == null) { throw new NullPointerException("helper must not be null"); } try { db = helper.getWritableDatabase(); super.runBare(); } finally { if (db.isOpen()) { db.close(); } } } }