ProviderTestCase2或RenamingDelegatingContext:在Android测试数据库? [英] Testing database on Android: ProviderTestCase2 or RenamingDelegatingContext?

查看:118
本文介绍了ProviderTestCase2或RenamingDelegatingContext:在Android测试数据库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我实现访问使用数据库 SQLiteOpenHelper 一些类中的android.database包(带图案DAO)。

I've implemented access to a database using SQLiteOpenHelper from the android.database package within some classes (with pattern DAO).

我使用的是 AndroidTestCase ,但是这会导致测试使用同一个数据库的应用程序写了一些JUnit测试这些类。

I wrote some junit tests for these classes using an AndroidTestCase but this causes the tests to use the same database as the application.

我读了 ProviderTestCase2 RenamingDelegatingContext 可以用来单独测试数据库。不幸我找不到任何好的教程/示例,说明如何来测试ProviderTestCase2 / RenamingDelegatingContext数据库。

I read that the ProviderTestCase2 or RenamingDelegatingContext can be used to test the database separately. Unluckily I couldn't find any nice tutorial/example that shows how to test a database with ProviderTestCase2/RenamingDelegatingContext.

任何人都可以点我的地方,或者给我一些提示或分享一些code数据库测试?!

Can anyone point me somewhere OR give me some tip OR share some code for database testing?!

Cheeerrrrsss! 乔治

Cheeerrrrsss!! Giorgio

推荐答案

无论是 ProviderTestCase RenamingDelegatingContext 将摧毁如果在它打开之前已经存在的数据库的情况下,所以在这个意义上,它们都具有对打开SQLite数据库相同的低层次的方法。

Both the ProviderTestCase and RenamingDelegatingContext will destroy the database if one already exists before opening it within it's context, so in that sense they both have the same low-level approach towards opening a SQLite database.

您在设置打开数据库在夹具利用这个(),这将然后确保你与每个测试用例前一个全新的数据库工作。

You leverage this by opening the database in your fixture in setUp(), which will then ensure that your working with a fresh database before each test case.

我会建议你去写的内容提供商,而不是创建数据库适配器。您可以使用一个通用的接口来访问数据,将其存储在数据库中或在网络上的某个地方,内容提供商的设计可以容纳在一点点IPC开销的成本来访问这些数据涉及到我们中的大多数不应该吨有关心。

I would suggest that you go for writing content providers rather than creating database adapters. You can use a common interface for accessing data, be it stored in the DB or somewhere over the network, the design of content providers can be accommodated to access such data at the cost of a bit of IPC overhead involved that most of us shouldn't have to care about.

如果你这样做访问SQLite数据库,该框架将全面管理在一个单独的进程为你的数据库连接。作为补充牛肉,在 ProviderTestCase2< ContentProvider的> 完全自举一个测试环境为内容提供商无需你一个写code一行

If you did this for accessing a SQLite database, the framework would completely manage the database connection for you in a separate process. As added beef, the ProviderTestCase2<ContentProvider> completely bootstraps a test context for your content provider without you having to a write a single line of code.

但是,这不是说,这是不是这样一个巨大的努力,做自举自己。所以,假设你有一个数据库适配器等;我们只专注于的open()获取写访问到我们的数据库,没有什么特别的:

But, that's not said it isn't such a huge effort to do the bootstrapping yourself. So supposing you had a database adapter as such; we'll just focus on open() for getting write access to our database, nothing fancy:

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 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);

        }

    }

    /**
     * Constructor - takes the provided context to allow for the database to be
     * opened/created.
     * 
     * @param context the Context within which to work.
     */
    public LastFmAdapter(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 LastFmAdapter open() throws SQLException {
        mDbHelper = new DatabaseHelper(mCtx);
        mDb = mDbHelper.getWritableDatabase();
        return this;
    }

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

}

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

Then you could write your test as such:

public final class MyAdapterTests extends AndroidTestCase {

    private static final String TEST_FILE_PREFIX = "test_";
private LastFmAdapter 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(上下文)。开()被调用时,将总是重新创建数据库。在 MyAdapter.DATABASE_CREATE_STATEMENT 你现在写每个测试将要对数据库的状态被调用。

So what's happening here is that the context implementation of RenamingDelegatingContext, once MyAdapter(context).open() is called, will always recreate the database. Each test you write now will be going against the state of the database after MyAdapter.DATABASE_CREATE_STATEMENT is called.

这篇关于ProviderTestCase2或RenamingDelegatingContext:在Android测试数据库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆