0

I have built a contact app and am trying to learn to write tests. At the moment my TestAddContact passes, except every time I run it, it is actually adding the data to the apps database. How can I make it so the test does not add to the actual apps data?

package com.domscott.contactapplication;

import android.content.Context;
import android.database.Cursor;

import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;

import junit.framework.TestCase;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import java.util.ArrayList;

import static org.junit.Assert.*;

@RunWith(AndroidJUnit4.class)
public class MyDatabaseHelperTest {

    private MyDatabaseHelper database;

    @Before
    public void setUp() throws Exception {
        database = new MyDatabaseHelper(ApplicationProvider.getApplicationContext());
    }
    @After
    public void tearDown() {
        database.close();
    }

    @Test
    public void TestAddContact() {

        ArrayList<String> idTest = new ArrayList<>();
        ArrayList<String> f_nameTest = new ArrayList<>();
        ArrayList<String> l_nameTest = new ArrayList<>();
        ArrayList<String> phoneTest = new ArrayList<>();

        database.addContact("dom","scott", "123");
        Cursor cursor = database.readData();
        while (cursor.moveToNext()) {
            idTest.add(cursor.getString(0));
            f_nameTest.add(cursor.getString(1));
            l_nameTest.add(cursor.getString(2));
            phoneTest.add(cursor.getString(3));

            Assert.assertEquals(f_nameTest.get(0), "dom");
        }
    }
}

Here is MyDatabaseHelper Class. I am trying to write tests for the methods inside of this.

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;

import androidx.annotation.Nullable;

import java.nio.charset.IllegalCharsetNameException;
import java.util.ArrayList;
import java.util.List;

//DataBase operations class
public class MyDatabaseHelper extends SQLiteOpenHelper {

    private Context context;
    private static final String DATABASE_NAME = "Contacts.db";
    private static final int DATABASE_VERSION = 1;

    private static final String TABLE_NAME = "contacts";
    private static final String COLUMN_ID = "_id";

    private static final String COLUMN_FIRST_NAME = "first_name";
    private static final String COLUMN_LAST_NAME = "last_name";
    private static final String COLUMN_PHONE = "_phone";
    //constructor
    MyDatabaseHelper(@Nullable Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        this.context = context;
    }
    //Create DB
    @Override
    public void onCreate(SQLiteDatabase db) {
        String query = "CREATE TABLE " + TABLE_NAME +
                " (" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                COLUMN_FIRST_NAME + " TEXT, " +
                COLUMN_LAST_NAME + " TEXT, " +
                COLUMN_PHONE + " TEXT);";
        db.execSQL(query);
    }

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

    //method for adding a contact to the DB
    void addContact(String firstName, String lastName, String phone) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues values = new ContentValues();

        values.put(COLUMN_FIRST_NAME, firstName);
        values.put(COLUMN_LAST_NAME, lastName);
        values.put(COLUMN_PHONE, phone);
        long result = db.insert(TABLE_NAME, null, values);

    }

    //Method that uses an SQL query for reading all the data from the DB to display on the mainActivity.
    Cursor readData() {
        String query = "SELECT * FROM " + TABLE_NAME;
        SQLiteDatabase db = this.getReadableDatabase();

        Cursor cursor = null;
        if(db != null) {
            cursor = db.rawQuery(query, null);
        }
        return cursor;
    }
    //Method using SQL query to update data of a contact
    void updateData(String row_id, String fName, String lName, String phone) {
        SQLiteDatabase db =this.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(COLUMN_FIRST_NAME, fName);
        values.put(COLUMN_LAST_NAME, lName);
        values.put(COLUMN_PHONE, phone);

        long result = db.update(TABLE_NAME, values, "_id=?", new String[]{row_id});
        if(result == -1) {
            Toast.makeText(context, "Failed to Update", Toast.LENGTH_SHORT).show();
        }else{
            Toast.makeText(context, "Update Successful", Toast.LENGTH_SHORT).show();
        }

    }
    //Contact deletion method
    void deleteContact(String row_id) {
        SQLiteDatabase db = this.getWritableDatabase();
        long result = db.delete(TABLE_NAME,"_id=?", new String[] {row_id});
        if (result == -1) {
            Toast.makeText(context, "Delete Failed", Toast.LENGTH_SHORT).show();
        }else{
            Toast.makeText(context, "Contact Deleted", Toast.LENGTH_SHORT).show();
        }
    }

    //Method using SQL query to select a random contact from the DB
    public Cursor getRandomContact()
    {
        SQLiteDatabase myDB = this.getWritableDatabase();
        String query = "SELECT * FROM " + TABLE_NAME +
                        " ORDER BY RANDOM() LIMIT 1";

        return myDB.rawQuery(query, null);
    }
}
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
Domandy
  • 9
  • 2
  • You should use something other than `ApplicationProvider.getApplicationContext` - https://stackoverflow.com/a/64572333/2308683 – OneCricketeer Apr 12 '21 at 04:32
  • @OneCricketeer I tried this. ```private MyDatabaseHelper database; Context context =InstrumentationRegistry.getInstrumentation().getTargetContext(); @Before public void setUp() throws Exception { database = new MyDatabaseHelper(context); }``` and got the same result. Any suggestions of what to use? – Domandy Apr 12 '21 at 04:47
  • Does your `MyDatabaseHelper` class do something that's specific to the app data itself? – OneCricketeer Apr 12 '21 at 04:50
  • @OneCricketeer I have added the class to the original post. The MyDatabaseHelper has all the methods for CRUD as well as a getRandomContact method. Am I doing something in there that is causing the issue? maybe in the OnCreate? – Domandy Apr 12 '21 at 05:03
  • 1
    You can also supply `null` for database name to create an in-memory database. – laalto Apr 12 '21 at 05:19
  • @laalto if i change database name to null, it does not save the data in the app when I add a contact. – Domandy Apr 13 '21 at 23:24
  • You can have different constructor calls for tests and app code. – laalto Apr 14 '21 at 06:01

1 Answers1

0

You can use in-memory(which will be created for test executing time) db for testes when setups db, or you can create DBs with different names for tests and app's user.

Artem Viter
  • 804
  • 7
  • 12