无法在Android中测试Realm unitest

时间:2016-09-01 16:02:42

标签: android unit-testing realm retrofit2

我通过Retrofit获取数据,并将数据写入Realm 所以我创建了一个Junitest来确保数据写入Real数据库

以下是Retrofit的代码

    public interface FixerIOAPI {
//   http://api.fixer.io/latest
    @GET("/latest")
    Observable<Bank> loadLatestEeurBaseRate();
}

以下是数据库控件的代码

public class RateDataSourceImpl implements RateDataSource {
    private Observable<Bank> bankAPI;


    public RateDataSourceImpl() {
        /*Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://api.fixer.io/")
                .addConverterFactory(GsonConverterFactory.create())
                 .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
        FixerIOAPI fixerIOAPi = retrofit.create(FixerIOAPI.class);
        bankAPI = fixerIOAPi.loadLatestEeurBaseRate();*/


    }


    @Override//        get the rate form the internet and write to the Realm
    public void refreshData(final RefreshCallback callback) {

        if (bankAPI == null) {
            callback.refreshFail("bankAPI or realm is null");
            return;
        }

        bankAPI.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<Bank>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {
                Log.d("RxRatitraft",e.toString());
                callback.refreshFail(e.toString());
            }

            @Override
            public void onNext(final Bank bank) {
                Realm realm = Realm.getDefaultInstance();
//                delete the old first
                deleteAllRate(realm);

                realm.executeTransaction(new Realm.Transaction() {
                    @Override
                    public void execute(Realm realm) {
                        Rates rates = bank.getRates();

                        if (rates == null) {
                            callback.refreshFail("Response null");
                            return;
                        }

//                       write at here

                        int todatDayint = Util.getTodayDate();

                        HashMap<String, Double> rateMap = rates.getRateMap();
                        for (Map.Entry<String, Double> entry : rateMap.entrySet()) {
                            Rate rate = realm.createObject(Rate.class);
                            rate.setName(entry.getKey());
                            rate.setRateBaseEur(entry.getValue());
                            rate.setUpdateDate(todatDayint);
                        }
                        callback.refreshSuccess();
                    }
                });
               /* realm.executeTransactionAsync(new Realm.Transaction() {
                    @Override
                    public void execute(Realm realm) {
                        Rates rates = bank.getRates();

                        if (rates == null) {
                            callback.refreshFail("Response null");
                            return;
                        }

//                       write at here

                        int todatDayint = Util.getTodayDate();

                        HashMap<String, Double> rateMap = rates.getRateMap();
                        for (Map.Entry<String, Double> entry : rateMap.entrySet()) {
                            Rate rate = realm.createObject(Rate.class);
                            rate.setName(entry.getKey());
                            rate.setRateBaseEur(entry.getValue());
                            rate.setUpdateDate(todatDayint);
                        }

                    }

                }, new Realm.Transaction.OnSuccess() {
                    @Override
                    public void onSuccess() {
                        callback.refreshSuccess();

                    }
                }, new Realm.Transaction.OnError() {
                    @Override
                    public void onError(Throwable error) {
                        callback.refreshFail(error.toString());
                    }
                });*/


            }
        });



    }

    //if need refresh,but can't,will return negative
    @Override
    public void convertValue(final String from, final String to, final double money, final ConvertValueCallback callback) {
        if (bankAPI != null) {
            if (hasCache()) {
//                has cache
                if (!isUpdateExpired()) {
//                    <24
//                    TODO calculate
                    double converted = getRealmandCalculate(from, to, money);
                    if (converted != -1) {
//                        converted success
                        callback.conertValueSuccess(converted);
                    } else {
//                        cpnvert fail
                        callback.conertValueFail("Cant convert");
                    }


                } else {
//                    >24,update
                    refreshData(new RefreshCallback() {
                        @Override
                        public void refreshSuccess() {
//                            online
                            //                    TODO calculate
                            double converted = getRealmandCalculate(from, to, money);
                            if (converted != -1) {
//                        converted success
                                callback.conertValueSuccess(converted);
                            } else {
//                        cpnvert fail
                                callback.conertValueFail("Cant convert");
                            }

                        }

                        @Override
                        public void refreshFail(String error) {
//                              offline
//                            TODO update fail
                            //                    TODO calculate
                            double converted = getRealmandCalculate(from, to, money);
                            if (converted != -1) {
//                        converted success
                                callback.conertValueSuccess(converted * -1);
//                                because update fail but convert success,so,return negative
                            } else {
//                        cpnvert fail
                                callback.conertValueFail("Cant convert");
                            }

                        }
                    });
                }
            } else {
//                no cache
                refreshData(new RefreshCallback() {
                    @Override
                    public void refreshSuccess() {
//                        TODO calculate
                        double converted = getRealmandCalculate(from, to, money);
                        if (converted != -1) {
//                        converted success
                            callback.conertValueSuccess(converted);
                        } else {
//                        cpnvert fail
                            callback.conertValueFail("Cant convert");
                        }
                    }

                    @Override
                    public void refreshFail(String error) {
//                      update fail
//                        TODO can't update
//                        TODO can't convert
                        callback.conertValueFail("No Rate information");
                    }
                });
            }
        } else {
            callback.conertValueFail("realm and bankAPI is null");
        }
    }

    private double getRealmandCalculate(String from, String to, double money) {
        Realm realm = Realm.getDefaultInstance();
        if (realm == null) {
            return -1;
        }
        Rate fromRateOBJ = realm.where(Rate.class).equalTo(RealmColumnName.COL_NAME, from).findAll().first();
        Rate toRateOBJ = realm.where(Rate.class).equalTo(RealmColumnName.COL_NAME, to).findAll().first();
        return calculate(fromRateOBJ.getRateBaseEur(), toRateOBJ.getRateBaseEur(), money);

    }

    private double calculate(double fromRate, double toRate, double value) {
        return toRate / fromRate * value;
    }

    private boolean hasCache() {
        Realm realm = Realm.getDefaultInstance();
        if (realm == null) {
            return false;
        }
        RealmQuery<Rate> query = realm.where(Rate.class);
        long number = query.count();
        return number > 0;
    }

    private boolean isUpdateExpired() {

        Realm realm = Realm.getDefaultInstance();
        if (realm == null) {
            return false;
        }
        RealmQuery<Rate> query = realm.where(Rate.class);
        Rate rate = query.findFirst();
        return rate.getUpdateDate() < Util.getTodayDate();

    }

    @Override
    public void deleteAllRate() {
        Realm realm = Realm.getDefaultInstance();
        if (realm != null) {
            RealmResults<Rate> rates = realm.where(Rate.class).findAll();
            realm.beginTransaction();
            long count = realm.where(Rate.class).count();
            for (int i = 0; i < count; i++) {
                rates.get(i).deleteFromRealm();
            }
            realm.commitTransaction();

        }

        realm.close();

    }

    @Override
    public void setBankAPI(Observable<Bank> bankAPI) {
        this.bankAPI = bankAPI;
    }

    private void deleteAllRate(Realm realm) {

        if (realm != null) {
            RealmResults<Rate> rates = realm.where(Rate.class).findAll();
            realm.beginTransaction();
            long count = realm.where(Rate.class).count();
            for (int i = 0; i < count; i++) {
                rates.get(i).deleteFromRealm();
            }
            realm.commitTransaction();

        }

    }
}

我想测试一下refreshData方法,所以我编写下面的代码,以确保数据可以写入Realm数据库

public class RateDataSourceImplTest {
    private RateDataSource dataSource;
    private Boolean success=false;
    private int count=0;

    @Before
    public void setUp() throws Exception {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://api.fixer.io/")
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
        FixerIOAPI fixerIOAPi = retrofit.create(FixerIOAPI.class);
        Observable<Bank> call = fixerIOAPi.loadLatestEeurBaseRate();

        dataSource = new RateDataSourceImpl();
        dataSource.setBankAPI(call);

        dataSource.deleteAllRate();


    }

    @Test
    public void testRefreshData() throws Exception {


        final Realm realm = Realm.getDefaultInstance();

        dataSource.refreshData(new RateDataSource.RefreshCallback() {
            @Override
            public void refreshSuccess() {
                success=true;
            }

            @Override
            public void refreshFail(String error) {

            }
        });
        Awaitility.await().atMost(20,TimeUnit.SECONDS).until(new Callable<Boolean>() {

            @Override
            public Boolean call() throws Exception {

                return success;
            }

        });
        RealmQuery<Rate> query = realm.where(Rate.class);
        RealmResults<Rate> result = query.findAll();
        for(int i=0;i<realm.where(Rate.class).count();i++){
            Rate rate = result.get(0);
            assertNotNull(rate.getName());
            assertNotNull(rate.getRateBaseEur());
            assertNotNull(rate.getUpdateDate());
        }

        dataSource.deleteAllRate();



    }
}

然而,realm.where(Rate.class).count()总是显示领域中的数字是0.我确保改造从互联网获取正确的数据。是否有人知道可以&#的原因39; t写入Realm数据库?

1 个答案:

答案 0 :(得分:1)

单元测试Realm不起作用,你需要模拟Realm或使用仪器测试。