37

I am new to junit testing.

Can anyone help me , how to test my SQLiteOpenHelper class.

Means what classes I have to implement and how to test my db and tables. I am using Eclipse IDE.

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
Kartihkraj Duraisamy
  • 3,171
  • 2
  • 25
  • 36

4 Answers4

65

As of API Level 24, RenamingDelegatingContext is deprecated. Another thread suggests to use Robolectric's RuntimeEnvironment.application as described in this Medium article.

The old answer for reference:

For a simple DatabaseHandler:

public class MyDatabase extends SQLiteOpenHelper {
    private static final String DATABASE_NAME = "database.db";
    private static final int DATABASE_VERSION = 1;

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

    @Override
    public void onCreate(SQLiteDatabase db){
        // some code
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // some code
    }
}

I created an AndroidTestCase:

public class DatabaseTest extends AndroidTestCase {
    private MyDatabase db;

    @Override
    public void setUp() throws Exception {
        super.setUp();
        RenamingDelegatingContext context = new RenamingDelegatingContext(getContext(), "test_");
        db = new MyDatabase(context);
    }

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

    //According to Zainodis annotation only for legacy and not valid with gradle>1.1:
    //@Test
    public void testAddEntry(){
        // Here I have my new database which is not connected to the standard database of the App
    }
}
Bilaal Rashid
  • 828
  • 2
  • 13
  • 21
Pietro
  • 788
  • 9
  • 8
  • 8
    +1 for the use of `RenamingDelegatingContext()`, really usefull for testing purpose. – eternay Feb 19 '13 at 12:27
  • 1
    Aren´t you missing a bit of code? Namely @Test annotations, a super.setUp() and a db.open()? – ravemir Jun 23 '13 at 17:24
  • 3
    I think the android-test-environment does not require Test annotations see: http://developer.android.com/tools/testing/testing_android.html The super.setUp() method is empty but technically you probably should include it. To get access to the database you would probably do something like: db.getWritableDatabase(); – Pietro Sep 08 '13 at 10:00
  • a db.open isn't necessarily needed, depending on the SQLOpenHelper. I keep my database inside my SQLOpenHelper and do a db.open (or getwriteabledatabase) inside the constructor and access it through functions. – Rev Tyler Dec 02 '13 at 06:34
  • 2
    In Android Studio with gradle:1.1.0, mockito-core:1.9.5 and junit:4.12 the @Test annotations are actually marked as an error, hence it seems no longer necessary or even allowed. Instead (as far as I know) prepend ur testcases with the prefix "test". – AgentKnopf May 06 '15 at 20:50
  • 1
    @Zainodis I updated the code according to your input – Pietro May 07 '15 at 12:56
  • @Pietro cool, thanks :) ! Btw I was wondering: how do you reset your tables before each test method? I am doing a simple database.execSQL("delete from mytable"); but it does not seem to do anything. I am passing this call a MyDatabase.getWritableDatabase() (SqliteOpenHelper) - any ideas? – AgentKnopf May 07 '15 at 19:18
  • 1
    @Zainodis ATM I am not developing for Android, but what about db.delete("mytable", null, null); in the tearDown Method, in https://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#delete(java.lang.String,%20java.lang.String,%20java.lang.String[]) it says, passing null deletes all rows in the table – Pietro May 08 '15 at 13:33
  • @Pietro man,I am an idiot xD ! I used getContext to access my database when trying to delete instead of using the RenamingDelegatingContext initialized in setUp() ! Your Method of deleting the rows works great, if the correct context is used. Thanks a lot - saved me a huge headache :) ! – AgentKnopf May 08 '15 at 23:03
  • RenamingDelegatingContext is now deprecated... refer to http://stackoverflow.com/questions/39987669/renamingdelegatingcontext-is-deprecated-how-do-we-test-sqlite-db-now for using Robolectric to test – Elye Oct 14 '16 at 16:05
4

You can write android database test in JUnit4 style as well. You just need to add following dependency in your database

androidTestCompile('com.android.support.test:runner:0.3'){
        exclude group: 'com.android.support', module: 'support-annotations'
    }

And mark you Test class as follows

@RunWith(AndroidJUnit4.class)
public class DatabaseTest {
   @Test
   public void myFirstTest(){
      //your test
   }
}
Ajit Singh
  • 2,436
  • 23
  • 27
2

RenamingDelegatingContext is now deprecated in v24. Use Robolectric to test. An example (in Kotlin) as below

@RunWith(RobolectricGradleTestRunner::class)
@Config(constants = BuildConfig::class, sdk = intArrayOf(LOLLIPOP), packageName = "com.elyeproj.simpledb")
class ExampleUnitTest {

    lateinit var dbHelper: DbHelper // This is your SQLOpenHelper class

    @Before
    fun setup() {
        dbHelper = DbHelper(RuntimeEnvironment.application) // Your new context from Robolectric
        dbHelper.clearDbAndRecreate() // A function just to clear and recreate DB
    }

    @Test
    @Throws(Exception::class)
    fun testDbInsertion() {

        // Given
        val testStr1 = "testing"
        val testStr2 = "testing"

        // When
        dbHelper.insertText(testStr1)
        dbHelper.insertText(testStr2)

        // Then
        assertEquals(dbHelper.getAllText(), "$testStr1-$testStr2-")
    }

    @After
    fun tearDown() {
        dbHelper.clearDb() // A function just to clear the DB
    }
}

You could get the entire project source from https://github.com/elye/demo_simpledb_test

You could get elaboration from https://medium.com/@elye.project/android-sqlite-database-unit-testing-is-easy-a09994701162#.s44tity8x

Elye
  • 53,639
  • 54
  • 212
  • 474
0

this question is very abstract. I recommend that you read the Android Testing Guide. It has some simple examples of testing Android Apps.

Android Testing Support Library

Android Testing Training

Without knowing your code, I suppose that your SQLiteOpenHelper is used by an Activity or Service. I think that this Activities/Services is that you must to test.

A good start should be ActivityInstrumentationTestCase2 for an Activity or ServiceTestCase for a Service.

I hope it help.

sabadow
  • 5,095
  • 3
  • 34
  • 51