【问题标题】:Can't test Realm in the Android unitest无法在 Android unitest 中测试 Realm
【发布时间】:2016-09-01 16:02:42
【问题描述】:

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

这是改造的代码

    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。我确保改造从互联网上获取正确的数据。有没有人知道原因? t 写入 Realm 数据库?

【问题讨论】:

    标签: android unit-testing realm retrofit2


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 2016-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-14
      • 2014-12-24
      • 1970-01-01
      相关资源
      最近更新 更多