简体   繁体   中英

Android Studio Unit test SQLiteDataBase is null

I'm new to Unit testing and I want to test my SQLiteDataBase.

I have a class named MySQLiteHelper that extends SQLiteOpenHelper . I have a class named LocationDataHandler that I use to add or delete elements from my DataBase. And I have a class LocationDataHandlerTest , that extends AndroidTestCase , to test my LocationDataHandler class.

I'm trying to test my SQLite Database but I seem to be a little bit lost between all the different contexts.

here is my code :

//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 !

as you can see I tried with many different contexts that i saw people use and work with. I really don't understand why it doesn't work in my case.

My problem is that the test is failing on the line "assertNotNull(db);" meaning i can never retrieve my dataBase.

Am I doing this the wrong way ? Am I not using the right context ?

Edit : Here is my logcat :

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)

Yes, it is a context issue. All those contexts (including the ones you commented out) are null.

You could create a context:

context = new MockContext();

To the same database (or other resources) as your application, you can use (since you're using AndroidTestCase):

context = getInstrumentation().getContext();

There's a proper way to created and use a RoamingDelegatingContext, but it doesn't appear that you need that for your test.

You may consider reading Android Testing Fundamentals to help understand some issues with testing and the level of access/resources needed.

While testing in android, we generally mock file and the database. If we are testing on real device, we don't want to affect the existing files. Thus in these cases using context directs the calls to file system of our specific application.

Hence we mock away these type of operations by using RenamingDelegatingContext . This class delegates to the given context, but performs database and file operations by a renamed database/file name. You should use context as following:

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

Extend your test class from AndroidTestCase and use mContext like below code sample:

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 is inherited to this class from AndroidTestCase class. That will work as I had the same problem.

For testing with Android Studio,

You should use MockContext instead of RenamingDelegatingContext .

Use InstrumentationTestCase .

For further information, see this answer. https://stackoverflow.com/a/29063736/1020456

Here is my code.

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
}

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM