【问题标题】:Android Studio Unit test SQLiteDataBase is nullAndroid Studio 单元测试 SQLiteDataBase 为空
【发布时间】:2015-05-28 14:41:53
【问题描述】:

我是单元测试的新手,我想测试我的 SQLiteDataBase。

我有一个名为 MySQLiteHelper 的类,它扩展了 SQLiteOpenHelper。 我有一个名为 LocationDataHandler 的类,用于在我的数据库中添加或删除元素。 我有一个类 LocationDataHandlerTest,它扩展了 AndroidTestCase,来测试我的 LocationDataHandler 类。

我正在尝试测试我的 SQLite 数据库,但我似乎有点迷失在所有不同的上下文之间。

这是我的代码:

//Context context = new Activity();

//IsolatedContext context = getMockContext();

//Context context = new MockContext();

//Context context = getInstrumentation().getContext();

  Context context = getContext();

  helper = new MySQLiteHelper(context);
  assertNotNull(helper);

  SQLiteDatabase db = helper.getWritableDatabase();
  assertNotNull(db); <---- it fails here !

如您所见,我尝试了许多不同的环境,我看到人们使用和使用这些环境。我真的不明白为什么它在我的情况下不起作用。

我的问题是测试在“assertNotNull(db);”行上失败了这意味着我永远无法检索我的数据库。

我做错了吗?我没有使用正确的上下文吗?

编辑:这是我的日志:

junit.framework.AssertionFailedError
    at junit.framework.Assert.fail(Assert.java:55)
    at junit.framework.Assert.assertTrue(Assert.java:22)
    at junit.framework.Assert.assertNotNull(Assert.java:256)
    at junit.framework.Assert.assertNotNull(Assert.java:248)
    at junit.framework.TestCase.assertNotNull(TestCase.java:417)
    at com.databerries.LocationDataHandlerTest.testAddLocation(LocationDataHandlerTest.java:72)

【问题讨论】:

  • 可以添加logcat吗?只是为了详细了解您的问题..
  • 你试过getInstrumentation.getTargetContext()吗?
  • 是的,它给我抛出了一个空指针异常:Context context = getInstrumentation().getTargetContext();
  • 我也有同样的问题。你找到解决办法了吗?
  • 幸运吗?我也卡在那部分,如果您有任何解决方案,请分享一下

标签: java android sqlite unit-testing


【解决方案1】:

是的,这是一个上下文问题。所有这些上下文(包括您注释掉的那些)都是空的。

你可以创建一个上下文:

context = new MockContext();

到与您的应用程序相同的数据库(或其他资源),您可以使用(因为您使用的是 AndroidTestCase):

context = getInstrumentation().getContext();

有一种创建和使用 RoamingDelegatingContext 的正确方法,但您的测试似乎不需要它。

您可以考虑阅读Android Testing Fundamentals,以帮助了解一些测试问题以及所需的访问权限/资源级别。

【讨论】:

  • 嗨!谢谢你的回答,但这些解决方案都没有奏效...... context = new MockContext();给我同样的错误,就是我的数据库为空。而上下文 = getInstrumentation().getContext();给我这个错误: com.databerries.LocationDataHandlerTest.testAddLocation(LocationDataHandlerTest.java:66) 处的 java.lang.NullPointerException (第 66 行是 context = getInstrumentation().getContext();)
  • @ThéoRichard 尝试将您的测试类型更改为 ActivityTestCase 或 InstrumentationTestCase。我刚刚意识到我误读了文档并认为 AndroidTestCase 是 InstrumentationTestCase 的子类(它实际上是 ActivityTestCase 的子类)。然后您可以重试 getInstrumentation().getContext() 调用。
  • 还是同样的错误,com.databerries.LocationDataHandlerTest.testAddLocation(LocationDataHandlerTest.‌​java:66) 处的 java.lang.NullPointerException (第 66 行是 context = getInstrumentation().getContext( );)
  • 为了确认,您将测试类型更改为 ActivityTestCase 或 InstrumentationTestCase?您的测试需要从 InstrumentationTestCase 继承才能正常工作。
  • 是的,我都试过了,它在这一行抛出了一个空指针异常:context = getInstrumentation().getContext();
【解决方案2】:

在 android 中进行测试时,我们通常会模拟文件和数据库。如果我们在真实设备上进行测试,我们不想影响现有文件。因此,在这些情况下,使用上下文将调用定向到我们特定应用程序的文件系统。

因此我们使用RenamingDelegatingContext 模拟掉这些类型的操作。此类委托给给定的上下文,但通过重命名的数据库/文件名执行数据库和文件操作。 您应该使用如下上下文:

RenamingDelegatingContext context = new RenamingDelegatingContext(getContext(), "test_db");
helper = new MySQLiteHelper(context);
assertNotNull(helper);
SQLiteDatabase db = helper.getWritableDatabase();
assertNotNull(db);

【讨论】:

  • @ThéoRichard 如果创建数据库的代码正确,您检查过您的 Helper 类吗?
【解决方案3】:

AndroidTestCase 扩展您的测试类并使用mContext,如下代码示例:

public class MyDbHelperTest extends AndroidTestCase {

private DatabaseHelper db;

@Before
public void setUp() throws Exception {
    super.setUp();
    db = DatabaseHelper.getInstance(mContext);
}

@After
public void tearDown() throws Exception {
    db.close();
    super.tearDown();
}

public void testOpeningDb() throws Exception {
    assertNotNull(db);
    SQLiteDatabase sqliteDb = db.getWritableDatabase();
    assertNotNull(sqliteDb);
  }

}

mContext 继承自 AndroidTestCase 类。 这会起作用,因为我遇到了同样的问题。

【讨论】:

    【解决方案4】:

    对于使用 Android Studio 进行测试,

    您应该使用MockContext 而不是RenamingDelegatingContext

    使用InstrumentationTestCase

    有关详细信息,请参阅此答案。 https://stackoverflow.com/a/29063736/1020456

    这是我的代码。

    public class DatabaseHelperTest extends InstrumentationTestCase{
    
    private DatabaseHelper db;
    
    @Before
    public void setUp() throws Exception {
        super.setUp();
    
        MockContext context = new MockContext();
        db = DatabaseHelper.getInstance(context);
    }
    
    @After
    public void tearDown() throws Exception {
        db.close();
        super.tearDown();
    }
    
    public void testInsertUserInteraction() throws Exception {
        assertNotNull(db.getReadableDatabase()); //should pass
    }
    

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-06
      • 1970-01-01
      • 1970-01-01
      • 2015-09-15
      相关资源
      最近更新 更多