Single choice recyclerView

Single choice recyclerView

When we want to Multiple choice in RecyclerView, we will need these things:

– String []
– Adapter with itemClickListener
– Activity or fragment
– activity_main (recyclerView)
– list_item (TextView, CheckBox)

We use notifydatasetchanged(), it’s very important than We understand this method.
You can check the full code in GitHub.

Our views activity_main.xml (recyclerView):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.thedeveloperworldisyours.fullrecycleview.single.SingleFragment">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/single_fragment_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</RelativeLayout>

and list_item.xml (TextView, CheckBox)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/single_list_item_text"
        android:layout_width="match_parent"
        android:layout_height="90dp"
        android:text="@string/app_name"
        android:typeface="monospace"
        android:layout_toLeftOf="@+id/single_list_item_check_button"
        android:gravity="center"
        android:textSize="@dimen/multiple_list_item_size_rock_stars"/>

    <RadioButton
        android:id="@+id/single_list_item_check_button"
        android:layout_width="wrap_content"
        android:layout_height="90dp"
        android:layout_alignParentRight="true"
        android:checked="false"
        android:clickable="false"
        android:focusable="false" />

</RelativeLayout>

Adapter with ClickListener


public class SingleRecyclerViewAdapter extends RecyclerView.Adapter<SingleRecyclerViewAdapter.DataObjectHolder> {

    private String[] mData;
    private static SingleClickListener sClickListener;
    private static int sSelected = -1;

    public SingleRecyclerViewAdapter(String[] mData) {
        this.mData = mData;
    }

    static class DataObjectHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        TextView mTextView;
        RadioButton mRadioButton;

        public DataObjectHolder(View itemView) {
            super(itemView);
            this.mTextView = (TextView) itemView.findViewById(R.id.single_list_item_text);
            this.mRadioButton = (RadioButton) itemView.findViewById(R.id.single_list_item_check_button);
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View view) {
            sSelected = getAdapterPosition();
            sClickListener.onItemClickListener(getAdapterPosition(), view);
        }
    }

    public void selectedItem() {
        notifyDataSetChanged();
    }

    void setOnItemClickListener(SingleClickListener clickListener) {
        sClickListener = clickListener;
    }

    @Override
    public DataObjectHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.single_list_item, parent, false);

        DataObjectHolder dataObjectHolder = new DataObjectHolder(view);
        return dataObjectHolder;
    }

    @Override
    public void onBindViewHolder(DataObjectHolder holder, int position) {
        holder.mTextView.setText(mData[position]);

        if (sSelected == position) {
            holder.mRadioButton.setChecked(true);
        } else {
            holder.mRadioButton.setChecked(false);
        }

    }

    @Override
    public int getItemCount() {
        return mData.length;
    }

    interface SingleClickListener {
        void onItemClickListener(int position, View view);
    }

}

Activity or fragment

public class SingleFragment extends Fragment implements SingleRecyclerViewAdapter.SingleClickListener {

    SingleRecyclerViewAdapter mAdapter;

    public SingleFragment() {
        // Required empty public constructor
    }

    public static SingleFragment newInstance() {
        return new SingleFragment();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.single_fragment, container, false);
        RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.single_fragment_recycler_view);

        String[] list = new String[]{"Jimi Hendrix", "David Bowie", "Jim Morrison", "Elvis Presley",
                "Mick Jagger", "Kurt Cobain", "Bob Dylan", "John Lennon", "Freddie Mercury", "Elton John", "Eric Clapton"};

        mAdapter = new SingleRecyclerViewAdapter(list);
        recyclerView.setAdapter(mAdapter);
        recyclerView.setHasFixedSize(true);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
        RecyclerView.ItemDecoration itemDecoration =
                new DividerVerticalItemDecoration(getActivity());
        recyclerView.addItemDecoration(itemDecoration);
        recyclerView.setLayoutManager(layoutManager);
        mAdapter.setOnItemClickListener(this);
        return view;
    }

    @Override
    public void onItemClickListener(int position, View view) {
        mAdapter.selectedItem();
    }
}

You can check the full code in GitHub.

Multiple choice recyclerView

Multiple choice recyclerView

The completed code GitHub

When we want to Multiple choice in RecyclerView, we will need these things:

– Data (String name, boolean selected)
– Adapter with itemClickListener
– Activity or fragment
– activity_main (recyclerView)
– list_item (TextView, CheckBox)

We use notifydatasetchanged(), it’s very important than We understand this method.

Out Data will have String and boolean, this boolean will save if user select or not the item.

public class MultipleData {

    private String mTitle;
    private boolean mBoolean;

    public MultipleData(String title, boolean mBoolean) {
        this.mTitle = title;
        this.mBoolean = mBoolean;
    }

    public String getTitle() {
        return mTitle;
    }

    public void setTitle(String mTitle) {
        this.mTitle = mTitle;
    }

    public boolean isBoolean() {
        return mBoolean;
    }

    public void setBoolean(boolean mBoolean) {
        this.mBoolean = mBoolean;
    }
}

Our views activity_main.xml (recyclerView)

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.thedeveloperworldisyours.fullrecycleview.multiple.MultipleFragment">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/multiple_fragment_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</FrameLayout>

and list_item.xml (TextView, CheckBox)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/multiple_list_item_text"
        android:layout_width="match_parent"
        android:layout_height="90dp"
        android:text="@string/app_name"
        android:typeface="monospace"
        android:layout_toLeftOf="@+id/multiple_list_item_check_button"
        android:gravity="center"
        android:textSize="@dimen/multiple_list_item_size_rock_stars"/>

    <RadioButton
        android:id="@+id/multiple_list_item_check_button"
        android:layout_width="wrap_content"
        android:layout_height="90dp"
        android:layout_alignParentRight="true"
        android:checked="false"
        android:clickable="false"
        android:focusable="false" />

</RelativeLayout>

Adapter with ClickListener

public class MultipleRecyclerViewAdapter extends RecyclerView
        .Adapter<MultipleRecyclerViewAdapter
        .DataObjectHolder> {

    private List<MultipleData> mList;
    private static MultipleClickListener sClickListener;

    MultipleRecyclerViewAdapter(List<MultipleData> mList) {
        this.mList = mList;
    }

    static class DataObjectHolder extends RecyclerView.ViewHolder
            implements View
            .OnClickListener {

        TextView mTextView;
        RadioButton mRadioButton;

         DataObjectHolder(View itemView) {
            super(itemView);
            mTextView = (TextView) itemView.findViewById(R.id.multiple_list_item_text);
            mRadioButton = (RadioButton) itemView.findViewById(R.id.multiple_list_item_check_button);
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            sClickListener.onItemClick(getAdapterPosition(), v);
        }
    }

    void changedData(int position) {
            if (mList.get(position).isBoolean()) {
                mList.get(position).setBoolean(false);
            } else {
                mList.get(position).setBoolean(true);
            }
        notifyDataSetChanged();
    }

    void setOnItemClickListener(MultipleClickListener myClickListener) {
        this.sClickListener = myClickListener;
    }

    @Override
    public DataObjectHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.multiple_list_item, parent, false);

        DataObjectHolder dataObjectHolder = new DataObjectHolder(view);
        return dataObjectHolder;
    }

    @Override
    public void onBindViewHolder(DataObjectHolder holder, int position) {
        holder.mTextView.setText(mList.get(position).getTitle());
        holder.mRadioButton.setChecked(mList.get(position).isBoolean());
    }

    @Override
    public int getItemCount() {
        return mList.size();
    }

    interface MultipleClickListener {
        void onItemClick(int position, View v);
    }


}

Activity or fragment

package com.thedeveloperworldisyours.fullrecycleview.multiple;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.thedeveloperworldisyours.fullrecycleview.R;
import com.thedeveloperworldisyours.fullrecycleview.swipe.DividerItemDecoration;

import java.util.ArrayList;
import java.util.List;

public class MultipleFragment extends Fragment implements MultipleRecyclerViewAdapter.MultipleClickListener{

    MultipleRecyclerViewAdapter mAdapter;

    public MultipleFragment() {
        // Required empty public constructor
    }

    public static MultipleFragment newInstance() {
        return new MultipleFragment();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.multiple_fragment, container, false);

        RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.multiple_fragment_recycler_view);

        MultipleData hendrix = new MultipleData("Jimi Hendrix", false);
        MultipleData bowie = new MultipleData("David Bowie", false);
        MultipleData morrison = new MultipleData("Jim Morrison", false);

        MultipleData presley = new MultipleData("Elvis Presley", false);
        MultipleData jagger = new MultipleData("Mick Jagger", false);
        MultipleData cobain = new MultipleData("Kurt Cobain", false);

        MultipleData dylan = new MultipleData("Bob Dylan", false);
        MultipleData lennon = new MultipleData("John Lennon", false);
        MultipleData mercury = new MultipleData("Freddie Mercury", false);

        MultipleData elton = new MultipleData("Elton John", false);
        MultipleData clapton = new MultipleData("Eric Clapton", false);

        List<MultipleData> list = new ArrayList<>();
        list.add(0, hendrix);
        list.add(1, bowie);
        list.add(2, morrison);

        list.add(3, presley);
        list.add(4, jagger);
        list.add(5, cobain);

        list.add(6, dylan);
        list.add(7, lennon);
        list.add(8, mercury);

        list.add(9, elton);
        list.add(10, clapton);

        mAdapter = new MultipleRecyclerViewAdapter(list);
        recyclerView.setAdapter(mAdapter);
        recyclerView.setHasFixedSize(true);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
        RecyclerView.ItemDecoration itemDecoration =
                new DividerItemDecoration(getActivity(), LinearLayoutManager.VERTICAL);
        recyclerView.addItemDecoration(itemDecoration);
        recyclerView.setLayoutManager(layoutManager);
        mAdapter.setOnItemClickListener(this);

        return view;
    }

    @Override
    public void onItemClick(int position, View v) {
        mAdapter.changedData(position);
    }
}

The completed code GitHub

RxJava retrolambda

RxJava retrolambda

This is a example how to use RxJava and Retrolambda on Android.
You can see the complete example in GitHub

Web Launcher

Java 8 introduced Lambdas Expressions, unfortunately Android does not support Java 8, so we are not able to take advantage of this with RxJava. Luckily there is a library called Retrolambda which backports lambdas to previous versions of Java. There is also a gradle plugin for Retrolambda that will allow the use of lambdas in an Android application.

In RxJava there are different elements:

1.BASIC(Observable)

2.ASYNCHRONOUS

3.SINGLES

4.SUBJECTS

5.MAP

6.DEBOUNCES

Basic

This method creates an Observable such that when an Observer subscribes, the onNext() of the Observer is immediately called with the argument provided to Observable.just(). The onCompleted() will then be called since the Observable has no other values to emit:

    Observable<List<String>> listObservable = Observable.just(getColorList());

    listObservable.subscribe(new Observer<List<String>>() { 

            @Override 
            public void onCompleted() { } 

            @Override 
            public void onError(Throwable e) { } 

            @Override
            public void onNext(List<String> colors) {
                mSimpleStringAdapter.setStrings(colors);
            }
    });

with lambda:

    Observable<List<String>> listObservable = Observable.just(getColorList());

    listObservable.subscribe(
                (List<String> colors)-> mSimpleStringAdapter.setStrings(colors),
                (error) -> {},
                () -> {});

Asynchronous

If we use it with Observable.just(), mRestClient.getFavoriteTvShows() will be evaluated immediately and block the UI thread. Enter the Observable.fromCallable() method. It gives us two important things: * The code for creating the emitted value is not run until someone subscribes to the Observer. * The creation code can be run on a different thread.

    Observable<List<String>> tvShowObservable = Observable.fromCallable(new Callable<List<String>>() { 

        @Override 
        public List<String> call() { 
            return mRestClient.getFavoriteTvShows(); 
        }
    });

    mTvShowSubscription = tvShowObservable
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        new Observer<List<String>>() {
                            @Override
                            public void onCompleted() {

                            }

                            @Override
                            public void onError(Throwable e) {

                            }

                            @Override
                            public void onNext(List<String> tvShows) {
                                displayTvShows(tvShows);
                            }
                        });

with lambda:

    Observable<List<String>> tvShowObservable = Observable.fromCallable(() -> mRestClient.getFavoriteTvShows());
    mTvShowSubscription = tvShowObservable
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                (List<String> tvShows) -> displayTvShows(tvShows),
                (error) -> {},
                () -> {});

Singles

There’s a simpler version of an Observable called a Single. Singles work almost exactly the same as Observables. But instead of there being an onCompleted(), onNext(), and onError(), there are only two callbacks: * onSuccess() and onError().

    Single<List<String>> tvShowSingle = Single.fromCallable(new Callable<List<String>>() { 

        @Override
        public List<String> call() throws Exception {
            mRestClient.getFavoriteTvShows(); 
        }
    });

    mTvShowSubscription = tvShowSingle
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new SingleSubscriber<List<String>>() {
                    @Override
                    public void onSuccess(List<String> tvShows) {
                        displayTvShows(tvShows);
                    }

                    @Override
                    public void onError(Throwable error) {
                        displayErrorMessage();
                    }
                }); 

with lambda:

    Single<List<String>> tvShowSingle = Single.fromCallable(() -> mRestClient.getFavoriteTvShows());

    mTvShowSubscription = tvShowSingle
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe((List<String> tvShows) -> displayTvShows(tvShows),
                    (Throwable error) ->  displayErrorMessage());

Subjects

Subjects are special objects that are both an Observable and an Observer. With a PublishSubject, as soon as you put something in one end of the pipe it immediately comes out the other.

    PublishSubject<Integer> mCounterEmitter = PublishSubject.create();
    mCounterEmitter.subscribe(new Observer<Integer>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Integer integer) {
                mCounterDisplay.setText(String.valueOf(integer));
            }
        });

with lambda:

    PublishSubject<Integer>  mCounterEmitter = PublishSubject.create();
    mCounterEmitter.subscribe(
                (Integer integer) ->  mCounterDisplay.setText(String.valueOf(integer)),
                (Throwable e) ->{},
                () -> { });

It increments a variable called mCounter. It calls onNext() on the mCounterEmitter with the new value of mCounter.

    mCounter ++;
    mCounterEmitter.onNext(mCounter);

Map

It’s a function that takes in one value and outputs another value. Usually there is some relationship between value put in to the map and the value that is output.

    Single.just(4).map(new Func1<Integer, String>() { 

        @Override 
        public String call(Integer integer) { 
            return String.valueOf(integer);
        } 
    }).subscribe(new SingleSubscriber<String>() { 

        @Override 
        public void onSuccess(String value) { 
            mValueDisplay.setText(value); 
        } 

        @Override 
        public void onError(Throwable error) { } 
        });

with lambda:

    Single.just(4).map((Integer integer) -> String.valueOf(integer))

                .subscribe((String value) -> mValueDisplay.setText(value),
                        (Throwable error) -> {});

Debounce

Everything together and a new concept: debounce. Let’s dive in. If you want to setup a PublishSubject such that it receives values the user types into a search box, fetches a list of suggestions based on that query, and then displays them.

    mSearchResultsSubject = PublishSubject.create();
    mTextWatchSubscription = mSearchResultsSubject
        .debounce(400, TimeUnit.MILLISECONDS)
        .observeOn(Schedulers.io())
        .map(new Func1<String, List<String>>() {

            @Override 
            public List<String> call(String s) { 
                return mRestClient.searchForCity(s); 
            } 
        })
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Observer<List<String>>() { 

            @Override 
            public void onCompleted() { }

            @Override 
            public void onError(Throwable e) { } 

            @Override
            public void onNext(List<String> cities) {
                handleSearchResults(cities); 
            }
        });
    });

with lambda:

    mSearchResultsSubject = PublishSubject.create();
    mTextWatchSubscription = mSearchResultsSubject
                .debounce(400, TimeUnit.MILLISECONDS)
                .observeOn(Schedulers.io())
                .map( (String string) -> mRestClient.searchForCity(string))
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe((List<String> cities) -> handleSearchResults(cities),
                        (Throwable e) -> {},
                        () -> {});

Libraries

The project is setup using:

You can see the complete example in GitHub

As the above only gives a rough overview of rxjava example I’d strongly recommend checking out the following:

Android Parameterized Test

Android Parameterized Test

If you have to make several test in one only method which provides parameters to be injected. The best practice is to add parameterized test

Addition operation is a good example:

    /**
     * Addition operation
     */
    public double add(double firstOperand, double secondOperand) {
        return firstOperand + secondOperand;
    }

The first step is to add these lines:

androidTestCompile 'com.android.support:support-annotations:24.0.0'
compile 'com.android.support:support-annotations:24.0.0'

In app/build.gradle because We use JUnitRunner test annotations and parameterized.

Provides parameters to be injected into the
* test class constructor

@Parameterized.Parameters
    public static Iterable<Object[]> data() {
        return Arrays.asList(new Object[][]{
                {0, 0, 0},
                {0, -1, -1},
                {2, 2, 4},
                {8, 8, 16},
                {16, 16, 32},
                {32, 0, 32},
                {64, 64, 128}});
    }

{fistOperand, secondOperand, result}

This is the full class:
-Iterable
-Construtor
-Setup
-test

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import android.test.suitebuilder.annotation.SmallTest;

import com.thedeveloperworldisyours.unitconverterpro.calculator.Calculator;
import com.thedeveloperworldisyours.unitconverterpro.calculator.CalculatorImpl;

import java.lang.Iterable;
import java.util.Arrays;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

/**
 * Created by javierg on 06/10/2016.
 */
@RunWith(Parameterized.class)
@SmallTest
public class CalculatorAddParameterizedTest {

    /**
     * @return {@link Iterable} that contains the values that should be passed to the constructor.
     * In this example we are going to use three parameters: operand one, operand two and the
     * expected result.
     */
    @Parameterized.Parameters
    public static Iterable<Object[]> data() {
        return Arrays.asList(new Object[][]{
                {0, 0, 0},
                {0, -1, -1},
                {2, 2, 4},
                {8, 8, 16},
                {16, 16, 32},
                {32, 0, 32},
                {64, 64, 128}});
    }

    private final double mOperandOne;
    private final double mOperandTwo;
    private final double mExpectedResult;

    private Calculator mCalculator;

    /**
     * Constructor that takes in the values specified in
     * {@link CalculatorAddParameterizedTest#data()}. The values need to be saved to fields in order
     * to reuse them in your tests.
     */
    public CalculatorAddParameterizedTest(double operandOne, double operandTwo,
                                          double expectedResult) {
        mOperandOne = operandOne;
        mOperandTwo = operandTwo;
        mExpectedResult = expectedResult;
    }

    @Before
    public void setUp() {
        mCalculator = new CalculatorImpl();
    }

    @Test
    public void testAdd_TwoNumbers() {
        double resultAdd = mCalculator.add(mOperandOne, mOperandTwo);
        assertThat(resultAdd, is(equalTo(mExpectedResult)));
    }
}

You can see a example in GitHub

Android SQLite Test

Android SQLite Test

Most of the secret of implementing SQLite Test with JUnit unit tests, is in the use of the assert methods in the class org.junit.Assert. In this text I will take a closer look at what assert methods are available in this class.

The most easy way is to use InstrumentationRegistry in android test package

mDataSource = new RateDataSource(InstrumentationRegistry.getTargetContext());

We can start with a normal SQLite class with CRUD (Create, Read, Update and Delete).

public class RateDataSource {
    // Database fields
    private SQLiteDatabase mDatabase;
    private MySQLiteHelper mDbHelper;
    private String[] mAllColumns = {MySQLiteHelper.COLUMN_ID,
            MySQLiteHelper.COLUMN_COIN, MySQLiteHelper.COLUMN_VALUE};

    public RateDataSource(Context context) {
        mDbHelper = new MySQLiteHelper(context);
    }

    public void open() throws SQLException {
        mDatabase = mDbHelper.getWritableDatabase();
    }

    public void close() {
        mDbHelper.close();
    }

    public Rate createRate(String coin, double value) {
        ContentValues values = new ContentValues();
        values.put(MySQLiteHelper.COLUMN_COIN, coin);
        values.put(MySQLiteHelper.COLUMN_VALUE, value);
        long insertId = mDatabase.insert(MySQLiteHelper.TABLE_RATE, null,
                values);
        Cursor cursor = mDatabase.query(MySQLiteHelper.TABLE_RATE,
                mAllColumns, MySQLiteHelper.COLUMN_ID + " = " + insertId, null,
                null, null, null);
        cursor.moveToFirst();
        Rate newComment = cursorToRate(cursor);
        cursor.close();
        return newComment;
    }

    public void deleteRate(Rate comment) {
        long id = comment.getId();
        System.out.println("Rate deleted with id: " + id);
        mDatabase.delete(MySQLiteHelper.TABLE_RATE, MySQLiteHelper.COLUMN_ID
                + " = " + id, null);
    }

    public List<Rate> getAllRates() {
        List<Rate> rates = new ArrayList<Rate>();

        Cursor cursor = mDatabase.query(MySQLiteHelper.TABLE_RATE,
                mAllColumns, null, null, null, null, null);

        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
            Rate rate = cursorToRate(cursor);
            rates.add(rate);
            cursor.moveToNext();
        }
        // make sure to close the cursor
        cursor.close();
        return rates;
    }

    private Rate cursorToRate(Cursor cursor) {
        Rate rate = new Rate();
        rate.setId(cursor.getLong(0));
        rate.setCoin(cursor.getString(1));
        rate.setValue(cursor.getDouble(2));
        return rate;
    }

    public void deleteAll() {

        mDatabase.delete(MySQLiteHelper.TABLE_RATE, null, null);
    }
}

After that you can start with your unit test, don’t forget to open and close database:

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));
    }
}

you can see the complete code in GitHub