android - 在 Android : ProviderTestCase2 or RenamingDelegatingContext? 上测试数据库

标签 android database testing android-testing

我已经使用 SQLiteOpenHelper 在某些类中的 android.database 包中实现了对数据库的访问(使用模式 DAO)。

我使用 AndroidTestCase 为这些类编写了一些 junit 测试,但这会导致测试使用与应用程序相同的数据库。

我读到 ProviderTestCase2RenamingDelegatingContext 可用于单独测试数据库。不幸的是,我找不到任何很好的教程/示例来展示如何使用 ProviderTestCase2/RenamingDelegatingContext 测试数据库。

谁能给我指点或给我一些提示或分享一些用于数据库测试的代码?!

欢呼! 乔治

最佳答案

ProviderTestCaseRenamingDelegatingContext如果在上下文中打开数据库之前已经存在数据库,则会销毁该数据库,因此从这个意义上说,它们都有相同的低级方法来打开 SQLite 数据库。

您可以通过在 setUp() 中打开夹具中的数据库来利用此功能。 ,这将确保您在每个测试用例之前使用新的数据库。

我建议您编写内容提供程序而不是创建数据库适配器。您可以使用通用接口(interface)来访问数据,无论是存储在数据库中还是网络上的某个地方,内容提供者的设计都可以适应访问此类数据,但代价是我们大多数人都应该这样做的 IPC 开销。不必关心。

如果您这样做是为了访问 SQLite 数据库,该框架将在一个单独的进程中为您完全管理数据库连接。作为添加的牛肉,ProviderTestCase2<ContentProvider>完全为您的内容提供者引导测试上下文,而无需您编写一行代码。

但是,这并不是说自己进行引导并不是一项巨大的努力。所以假设你有一个这样的数据库适配器;我们只关注 open()为了获得对我们数据库的写访问权,没什么特别的:

public class MyAdapter {

    private static final String DATABASE_NAME = "my.db";
    private static final String DATABASE_TABLE = "table";
    private static final int DATABASE_VERSION = 1;


    /**
     * Database queries
     */
    private static final String DATABASE_CREATE_STATEMENT = "some awesome create statement";

    private final Context mCtx;
    private SQLiteDatabase mDb;
    private DatabaseHelper mDbHelper;

    private static class DatabaseHelper extends SQLiteOpenHelper {

        public DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(DATABASE_CREATE_STATEMENT);  
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int a, int b) {
            // here to enable this code to compile
        }
    }

    /**
     * Constructor - takes the provided context to allow for the database to be
     * opened/created.
     * 
     * @param context the Context within which to work.
     */
    public MyAdapter(Context context) {
        mCtx = context;
    }

    /**
        * Open the last.fm database. If it cannot be opened, try to create a new
        * instance of the database. If it cannot be created, throw an exception to
        * signal the failure.
        * 
        * @return this (self reference, allowing this to be chained in an
        *         initialization call)
        * @throws SQLException if the database could be neither opened or created
        */
    public MyAdapter open() throws SQLException {
        mDbHelper = new DatabaseHelper(mCtx);
        mDb = mDbHelper.getWritableDatabase();
        return this;
    }

    public void close() {
            mDbHelper.close();
        }

}

然后你可以这样写你的测试:

public final class MyAdapterTests extends AndroidTestCase {

    private static final String TEST_FILE_PREFIX = "test_";
private MyAdapter mMyAdapter;

@Override
protected void setUp() throws Exception {
    super.setUp();

    RenamingDelegatingContext context 
        = new RenamingDelegatingContext(getContext(), TEST_FILE_PREFIX);

    mMyAdapter = new MyAdapter(context);
    mMyAdapter.open();
}

@Override
protected void tearDown() throws Exception {
    super.tearDown();

    mMyAdapter.close();
    mMyAdapter = null;
}

public void testPreConditions() {
    assertNotNull(mMyAdapter);
}

}

所以这里发生的是 RenamingDelegatingContext 的上下文实现, 一次 MyAdapter(context).open()被调用,将始终重新创建数据库。您现在编写的每个测试都将与 MyAdapter.DATABASE_CREATE_STATEMENT 之后的数据库状态相反。叫做。

关于android - 在 Android : ProviderTestCase2 or RenamingDelegatingContext? 上测试数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3096378/

相关文章:

android - 具有可点击区域的可缩放 SVG - Android

android - 按钮上的渐变和阴影

java - Android Studio 无法解析类中的方法

mysql - 如何将模拟到Excel文件中的数据导入到MySql数据库表中?

perl - 在 Perl 中测试 SUPER::methods 的分支分配

python - 如何一次并行执行多个pytest套件(文件)

android - 从 native Android 相机应用程序捕获黑白照片

java - JDBC 和 MySql 安装配置

python - MySQLdb 和使用 CursorUseResultMixIn 的大查询

java - 有没有办法比较不同格式的时间戳?