Android SQLite Database Unit Testing

2020-02-28 02:37发布

I'm new to android app development and I just made a note app. I want to do unit tests for the insertNote, readNote and updateNote methods for the database. How do I go about this? This is the code for my database. Thanks.

public class  DatabaseManager extends SQLiteOpenHelper {


public static final String Database_Name = "Notes Database";
public static final String Table_Name = "notes";

public static final String Column_id = "textId";
public static final String Column_title = "textTitle";
public static final String Column_body = "textBody";

public DatabaseManager(Context context){
    super(context, Database_Name, null, 1);
}

@Override
public void onCreate(SQLiteDatabase db){
    db.execSQL("CREATE TABLE " + Table_Name + " (" + Column_id +
            " INTEGER PRIMARY KEY AUTOINCREMENT, " + Column_title +
            " TEXT, " + Column_body + " TEXT)");
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
    db.execSQL("DROP TABLE IF EXISTS" + Table_Name);
    onCreate(db);
}

public void insertNote(Note note){
    SQLiteDatabase db = this.getWritableDatabase();

    ContentValues values = new ContentValues();
    values.put(Column_title, note.getTextTitle());
    values.put(Column_body, note.getTextBody());

    boolean result = db.insert(Table_Name, null, values) > 0;
    if (result == true)
        Log.d("Create", "Data Has Been Saved");
    db.close();
}

public Cursor readNote(int id){
    SQLiteDatabase db = this.getReadableDatabase();

    Cursor cursor = db.rawQuery("SELECT * FROM " + Table_Name + " WHERE _ROWID_ = " + id, null);

    if (cursor != null){
        cursor.moveToFirst();
    }

    Note myNote = new Note();
    myNote.textId = cursor.getInt(cursor.getColumnIndex(Column_id));
    myNote.textTitle = cursor.getString(cursor.getColumnIndex(Column_title));

    return cursor;
}

public ArrayList<String> getNoteList(){
    ArrayList<String> noteList =  new ArrayList<>();
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.rawQuery("SELECT * FROM " + Table_Name, null);
    cursor.moveToFirst();

    if (cursor.moveToFirst()){
        do{
            //noteList.add(cursor.getInt(cursor.getColumnIndex(Column_id)));
            noteList.add(cursor.getString(cursor.getColumnIndex(Column_title)));
        }
        while (cursor.moveToNext());
    }

    return noteList;
}

public int updateNote(Note note){
    SQLiteDatabase db = this.getWritableDatabase();

    ContentValues values = new ContentValues();
    values.put("textTitle", note.getTextTitle());
    values.put("textBody", note.getTextBody());

    int update = db.update(Table_Name, values, Column_id + " = ?", new String[]{Integer.toString(note.getTextId())});
    return update;
}

public Integer deleteNote(int id){
    SQLiteDatabase db = this.getWritableDatabase();
   return db.delete(Table_Name, Column_id + " = ?", new String[]{Integer.toString(id)} );
}

public int getCount(){
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db.rawQuery("SELECT * FROM " + Table_Name, null);
    cursor.close();

    return cursor.getCount();
}

}

3条回答
祖国的老花朵
2楼-- · 2020-02-28 03:05

Try to find some tutorials, articles about unit testing SQLite database in Java. Unit Testing in Java and Android is certainly the same.

Although you would find these topics on Stack:

How to test Android sqlite with junit?

How to test methods that deal with SQLite database in android?

or this article:

Android Easy SQLite With Unit Tests

According to testing SQLite databese with Junit, check this:

Android JUnit test for SQLiteOpenHelper

where you would find this solution:

For a simple DatabaseHandler:

<!-- language: java -->

    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:

<!-- language: java -->

  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 wich is not connected to the standard database of the App
      }
  }

Read also:

Using Junit to test writing and reading to SQLite

Testing SQLiteOpenHelper subclass with JUnit

查看更多
SAY GOODBYE
3楼-- · 2020-02-28 03:18

This answer suggests the Roboelectric library. That worked for me. It's faster than an instrumented test, which has to run in an emulator.

查看更多
够拽才男人
4楼-- · 2020-02-28 03:27

One way to implement SQLite testing is with an instrumented unit test, using the InstrumentationRegistry in the Android test package to obtain a Context.

Here is an example from a tutorial and an example on GitHub:

import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.LargeTest;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.List;

import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

@RunWith(AndroidJUnit4.class)
@LargeTest
public class SQLiteTest {

    private RateDataSource mDataSource;

    @Before
    public void setUp(){
        mDataSource = new RateDataSource(InstrumentationRegistry.getTargetContext());
        mDataSource.open();
    }

    @After
    public void finish() {
        mDataSource.close();
    }

    @Test
    public void testPreConditions() {
        assertNotNull(mDataSource);
    }

    @Test
    public void testShouldAddExpenseType() throws Exception {
        mDataSource.createRate("AUD", 1.2);
        List<Rate> rate = mDataSource.getAllRates();

        assertThat(rate.size(), is(1));
        assertTrue(rate.get(0).toString().equals("AUD"));
        assertTrue(rate.get(0).getValue().equals(1.2));
    }

    @Test
    public void testDeleteAll() {
        mDataSource.deleteAll();
        List<Rate> rate = mDataSource.getAllRates();

        assertThat(rate.size(), is(0));
    }

    @Test
    public void testDeleteOnlyOne() {
        mDataSource.createRate("AUD", 1.2);
        List<Rate> rate = mDataSource.getAllRates();

        assertThat(rate.size(), is(1));

        mDataSource.deleteRate(rate.get(0));
        rate = mDataSource.getAllRates();

        assertThat(rate.size(), is(0));
    }

    @Test
    public void testAddAndDelete() {
        mDataSource.deleteAll();
        mDataSource.createRate("AUD", 1.2);
        mDataSource.createRate("JPY", 1.993);
        mDataSource.createRate("BGN", 1.66);

        List<Rate> rate = mDataSource.getAllRates();
        assertThat(rate.size(), is(3));

        mDataSource.deleteRate(rate.get(0));
        mDataSource.deleteRate(rate.get(1));

        rate = mDataSource.getAllRates();
        assertThat(rate.size(), is(1));
    }
}
查看更多
登录 后发表回答