Android Robolectric – ContentProvider中queryBuilder.query()中的RuntimeException / InstantiationException

我在ContentProvider上进行了大约十次测试,只使用了sqlite; all pass保存在Content Provider的query()方法中通过queryBuilder.query()的两个.

正在测试的方法在实际应用中起作用!

这是API 17 r2和RoboLectric:
robolectric-2.0-α-3-20130417.013705-46-罐与 – dependencies.jar

@Override
public Cursor query(Uri uri,String[] projection,String selection,String[] selectionArgs,String sortOrder) {
    Log.d(Constants.TAG,"MyContentProvider.query()");
    switch(matcher.match(uri)) {
    case ITEM: // OK
        selection = "_id = ?";
        selectionArgs = new String[]{ Long.toString(ContentUris.parseId(uri)) };
    case ITEMS: // OK
        break;
    default:
        throw new IllegalArgumentException("Did not recognize URI " + uri);
    }
    // build the query with sqliteQueryBuilder
    sqliteQueryBuilder qBuilder = new sqliteQueryBuilder();
    qBuilder.setTables(TABLE_NAME);

    // query the database and get result in cursor
    final sqliteDatabase db = mDatabase.getReadableDatabase();
    Cursor resultCursor = qBuilder.query(db,// Line 112 in trace
            projection,selection,selectionArgs,null,sortOrder,null);
    resultCursor.setNotificationUri(getContext().getContentResolver(),uri);
    return resultCursor;
}

这是追溯:

java.lang.RuntimeException: java.lang.InstantiationException
    at org.robolectric.bytecode.ShadowWrangler.createShadowFor(ShadowWrangler.java:300)
    at org.robolectric.bytecode.ShadowWrangler.initializing(ShadowWrangler.java:74)
    at org.robolectric.bytecode.RobolectricInternals.initializing(RobolectricInternals.java:90)
    at android.database.sqlite.sqliteQuery.$$robo$init(sqliteQuery.java)
    at android.database.sqlite.sqliteClosable.<init>(sqliteClosable.java:26)
    at android.database.sqlite.sqliteProgram.<init>(sqliteProgram.java:41)
    at android.database.sqlite.sqliteQuery.<init>(sqliteQuery.java:37)
    at android.database.sqlite.sqliteDirectCursorDriver.query(sqliteDirectCursorDriver.java:44)
    at android.database.sqlite.sqliteDatabase.rawQueryWithFactory(sqliteDatabase.java:1314)
    at android.database.sqlite.sqliteQueryBuilder.query(sqliteQueryBuilder.java:400)
    at android.database.sqlite.sqliteQueryBuilder.query(sqliteQueryBuilder.java:333)
    at com.example.readingsprovider.ReadingsContentProvider.query(ReadingsContentProvider.java:112)
    at com.example.readingsprovider.test.ContentProviderTest.testUpdateMultipleWithoutWhere(ContentProviderTest.java:110)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:267)
    at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
    at org.junit.runners.BlockJUnit4ClassRunner.runchild(BlockJUnit4ClassRunner.java:71)
    at org.junit.runners.BlockJUnit4ClassRunner.runchild(BlockJUnit4ClassRunner.java:49)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runchildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:202)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.InstantiationException
    at sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:30)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at java.lang.class.newInstance0(Class.java:357)
    at java.lang.class.newInstance(Class.java:310)
    at org.robolectric.bytecode.ShadowWrangler.createShadowFor(ShadowWrangler.java:293)
    at org.robolectric.bytecode.ShadowWrangler.initializing(ShadowWrangler.java:74)
    at org.robolectric.bytecode.RobolectricInternals.initializing(RobolectricInternals.java:90)
    at android.database.sqlite.sqliteQuery.$$robo$init(sqliteQuery.java)
    at android.database.sqlite.sqliteClosable.<init>(sqliteClosable.java:26)
    at android.database.sqlite.sqliteProgram.<init>(sqliteProgram.java:41)
    at android.database.sqlite.sqliteQuery.<init>(sqliteQuery.java:37)
    at android.database.sqlite.sqliteDirectCursorDriver.$$robo$$sqliteDirectCursorDriver_7ac1_query(sqliteDirectCursorDriver.java:44)
    at android.database.sqlite.sqliteDirectCursorDriver.query(sqliteDirectCursorDriver.java)
    at android.database.sqlite.sqliteDatabase.$$robo$$sqliteDatabase_ab15_rawQueryWithFactory(sqliteDatabase.java:1314)
    at android.database.sqlite.sqliteDatabase.rawQueryWithFactory(sqliteDatabase.java)
    at android.database.sqlite.sqliteQueryBuilder.$$robo$$sqliteQueryBuilder_ba4d_query(sqliteQueryBuilder.java:400)
    at android.database.sqlite.sqliteQueryBuilder.query(sqliteQueryBuilder.java)
    at android.database.sqlite.sqliteQueryBuilder.$$robo$$sqliteQueryBuilder_ba4d_query(sqliteQueryBuilder.java:333)
    at android.database.sqlite.sqliteQueryBuilder.query(sqliteQueryBuilder.java)
    at com.example.readingsprovider.ReadingsContentProvider.query(ReadingsContentProvider.java:112)
    at com.example.readingsprovider.test.ContentProviderTest.testUpdateMultipleWithoutWhere(ContentProviderTest.java:110)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    ... 21 more

可以告诉我这是否是Robolectric的限制,还是我的不好?非常感谢!

附:如果Reflection API将失败的类名放在InstantiationException消息中,难道不是梦幻般的吗?

解决方法

我的项目有同样的问题,终于能够用一些谷歌搜索和U Avalos的前一个答案来解决

1.创建自定义sqliteShadow

@Implements(value = sqliteDatabase.class,inheritImplementationMethods = true)
public class CustomsqliteShadow extends ShadowsqliteDatabase {

    @Implementation
    public Cursor rawQueryWithFactory (sqliteDatabase.CursorFactory cursorFactory,String sql,String editTable,CancellationSignal cancellationSignal) {
      return rawQueryWithFactory(cursorFactory,sql,editTable);
    }
}

2.将@Config注释添加到测试中

要使用自定义阴影类,可以在robolectric2中使用@Config注释

@RunWith(RobolectricTestRunner.class)
@Config( shadows = {CustomsqliteShadow.class})
public class ContentProviderTest {

参考

http://robolectric.blogspot.co.at/2013/05/configuring-robolectric-20.html

相关文章

Android性能优化——之控件的优化 前面讲了图像的优化,接下...
前言 上一篇已经讲了如何实现textView中粗字体效果,里面主要...
最近项目重构,涉及到了数据库和文件下载,发现GreenDao这个...
WebView加载页面的两种方式 一、加载网络页面 加载网络页面,...
给APP全局设置字体主要分为两个方面来介绍 一、给原生界面设...
前言 最近UI大牛出了一版新的效果图,按照IOS的效果做的,页...