Realm 失败的仪器测试
Instrumented test with Realm failing
我正在实施仪器测试来测试使用 Realm 的数据库数据源 class。所以现在我面临一些关于如何使用固定装置以及如何模拟 Realm 的问题。
我的数据库数据源如下所示:
public class DatabaseDataSource {
private Realm realm;
public DatabaseDataSource(Realm realm) {
this.realm = realm;
}
public Observable<RealmResults> getContacts(String firstName, String lastName, String city, String zipCode) {
final RealmQuery realmQuery = realm.where(Contact.class);
if(!TextUtils.isEmpty(firstName)) {
realmQuery.contains("firstName", firstName);
}
if(!TextUtils.isEmpty(lastName)) {
realmQuery.contains("lastName", lastName));
}
if(!TextUtils.isEmpty(city)) {
realmQuery.contains("city", city);
}
if(!TextUtils.isEmpty(zipCode)) {
realmQuery.contains("zipCode", zipCode);
}
return realmQuery.findAll()
.asObservable();
}
}
我想在我的模拟领域中有一个联系人列表,这样我就可以检查过滤是否正常工作。我怎样才能做到这一点?
我试过:
@RunWith(AndroidJUnit4.class)
public class DatabaseDataSourceTest extends BaseInstrumentedTest{
private DatabaseDataSource databaseDataSource;
private List<Contact> contacts;
@Before
public void setup() {
Realm.init(InstrumentationRegistry.getTargetContext());
Realm.setDefaultConfiguration(new RealmConfiguration.Builder().build());
databaseDataSource = new DatabaseDataSource(new DatabaseClient());
}
@Test
public void trial() throws Exception {
subscribeContactsListObservable(databaseDataSource.getContacts("firstName", null, null, null));
assertEquals(2, contacts.size());
}
private void subscribeContactsListObservable(final Observable<RealmResults> observable) {
notaries = null;
observable.map(new Func1<RealmResults, List<Contact>>() {
@Override
public List<Notary> call(RealmResults realmResults) {
return realmResults != null? new ArrayList<>(realmResults) : null;
}
}).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<List<Contact>>() {
@Override
public void onCompleted() {
contacts = null;
}
@Override
public void onError(Throwable e) {
contacts = null;
}
@Override
public void onNext(List<Contact> contactsList) {
contacts = contactsList;
}
});
}
}
但是在执行 Observable.subscribe 时测试失败,但出现以下异常:
You can't register a listener from a non-Looper thread or IntentService thread.
我可以做什么?
提前致谢
显然你的 getContacts()
方法 运行 在非循环后台线程上,它不适用于我们的更改侦听器(因此我们的 asObservable()
方法)。
您可以只创建可观察对象,但请记住,它会发出您的列表一次,然后完成。要持续更新,您需要在 Looper 线程上。
return Observable.just(realmQuery.findAll());
好吧,它在该错误消息中专门告诉您问题的解决方案:
You can't register a listener from **a non-Looper thread** or IntentService thread.
这是因为 asObservable()
需要注册一个 RealmChangeListener
才能监听 Realm 中的变化。
检测线程是非循环线程,这意味着您无法监听其中的变化。
解决方案,您需要使用一个Looper 线程(如主线程),或者创建一个Looper 线程,并在该looper 线程中创建Realm 实例。方便的是,RxAndroid 具有所谓的 LooperScheduler which you can create using AndroidSchedulers.from(Looper),它允许您在任意循环线程上执行逻辑。
一种可能性正在研究 Realm already tests their looper-related stuff with this RunInLooperThread test rule。
这是我的一项测试的片段:
public class PlaybackDatabaseTest extends ApplicationTestCase<Application> {
public PlaybackDao dao;
public PlaybackDatabaseTest(){ super(Application.class);}
@Override
protected void setUp() throws Exception {
super.setUp();
DatabaseModule module = new DatabaseModule();
RealmConfiguration config = module.providePlaybackRealmConfiguration(getContext());
dao = module.providePlaybackDatabase(config);
}
public void testAddingPlaylistAndDeletingDatabase() {
dao.purgeDatabase();
int id1 = 0;
Playlist playlist = createTestPlaylist(id1, 0, 100);
dao.addPlaylist(playlist);
boolean exist1 = dao.isPlaylistExist(String.valueOf(id1));
assertTrue(exist1);
dao.purgeDatabase();
exist1 = dao.isPlaylistExist(String.valueOf(id1));
assertFalse(exist1);
}
}
但是,它使用 Dagger2 创建数据库 'data access object' .
Realm 可以从主线程运行,使用 Observable.toblocking() 所以你的
测试线程将等到 jub 完成。
Realm使用Android的Handler进行并发(.map(), .flatmap() operators return results on Schedulers.computation() by default),所以要解决Handler问题使用 ApplicationTestCase.
我正在实施仪器测试来测试使用 Realm 的数据库数据源 class。所以现在我面临一些关于如何使用固定装置以及如何模拟 Realm 的问题。 我的数据库数据源如下所示:
public class DatabaseDataSource {
private Realm realm;
public DatabaseDataSource(Realm realm) {
this.realm = realm;
}
public Observable<RealmResults> getContacts(String firstName, String lastName, String city, String zipCode) {
final RealmQuery realmQuery = realm.where(Contact.class);
if(!TextUtils.isEmpty(firstName)) {
realmQuery.contains("firstName", firstName);
}
if(!TextUtils.isEmpty(lastName)) {
realmQuery.contains("lastName", lastName));
}
if(!TextUtils.isEmpty(city)) {
realmQuery.contains("city", city);
}
if(!TextUtils.isEmpty(zipCode)) {
realmQuery.contains("zipCode", zipCode);
}
return realmQuery.findAll()
.asObservable();
}
}
我想在我的模拟领域中有一个联系人列表,这样我就可以检查过滤是否正常工作。我怎样才能做到这一点? 我试过:
@RunWith(AndroidJUnit4.class)
public class DatabaseDataSourceTest extends BaseInstrumentedTest{
private DatabaseDataSource databaseDataSource;
private List<Contact> contacts;
@Before
public void setup() {
Realm.init(InstrumentationRegistry.getTargetContext());
Realm.setDefaultConfiguration(new RealmConfiguration.Builder().build());
databaseDataSource = new DatabaseDataSource(new DatabaseClient());
}
@Test
public void trial() throws Exception {
subscribeContactsListObservable(databaseDataSource.getContacts("firstName", null, null, null));
assertEquals(2, contacts.size());
}
private void subscribeContactsListObservable(final Observable<RealmResults> observable) {
notaries = null;
observable.map(new Func1<RealmResults, List<Contact>>() {
@Override
public List<Notary> call(RealmResults realmResults) {
return realmResults != null? new ArrayList<>(realmResults) : null;
}
}).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<List<Contact>>() {
@Override
public void onCompleted() {
contacts = null;
}
@Override
public void onError(Throwable e) {
contacts = null;
}
@Override
public void onNext(List<Contact> contactsList) {
contacts = contactsList;
}
});
}
}
但是在执行 Observable.subscribe 时测试失败,但出现以下异常:
You can't register a listener from a non-Looper thread or IntentService thread.
我可以做什么?
提前致谢
显然你的 getContacts()
方法 运行 在非循环后台线程上,它不适用于我们的更改侦听器(因此我们的 asObservable()
方法)。
您可以只创建可观察对象,但请记住,它会发出您的列表一次,然后完成。要持续更新,您需要在 Looper 线程上。
return Observable.just(realmQuery.findAll());
好吧,它在该错误消息中专门告诉您问题的解决方案:
You can't register a listener from **a non-Looper thread** or IntentService thread.
这是因为 asObservable()
需要注册一个 RealmChangeListener
才能监听 Realm 中的变化。
检测线程是非循环线程,这意味着您无法监听其中的变化。
解决方案,您需要使用一个Looper 线程(如主线程),或者创建一个Looper 线程,并在该looper 线程中创建Realm 实例。方便的是,RxAndroid 具有所谓的 LooperScheduler which you can create using AndroidSchedulers.from(Looper),它允许您在任意循环线程上执行逻辑。
一种可能性正在研究 Realm already tests their looper-related stuff with this RunInLooperThread test rule。
这是我的一项测试的片段:
public class PlaybackDatabaseTest extends ApplicationTestCase<Application> {
public PlaybackDao dao;
public PlaybackDatabaseTest(){ super(Application.class);}
@Override
protected void setUp() throws Exception {
super.setUp();
DatabaseModule module = new DatabaseModule();
RealmConfiguration config = module.providePlaybackRealmConfiguration(getContext());
dao = module.providePlaybackDatabase(config);
}
public void testAddingPlaylistAndDeletingDatabase() {
dao.purgeDatabase();
int id1 = 0;
Playlist playlist = createTestPlaylist(id1, 0, 100);
dao.addPlaylist(playlist);
boolean exist1 = dao.isPlaylistExist(String.valueOf(id1));
assertTrue(exist1);
dao.purgeDatabase();
exist1 = dao.isPlaylistExist(String.valueOf(id1));
assertFalse(exist1);
}
}
但是,它使用 Dagger2 创建数据库 'data access object' .
Realm 可以从主线程运行,使用 Observable.toblocking() 所以你的 测试线程将等到 jub 完成。
Realm使用Android的Handler进行并发(.map(), .flatmap() operators return results on Schedulers.computation() by default),所以要解决Handler问题使用 ApplicationTestCase.