我通过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数据库?
答案 0 :(得分:1)
单元测试Realm不起作用,你需要模拟Realm或使用仪器测试。