2016-09-22 109 views
1

我有一个RealmManager类,为了执行CRUD我有几个方法。这是我在这门课的save方法。当我插入数据库时​​,领域引发NullPointerException

public void save(final List<PointOfInterest> pointOfInterestList) { 
    if (mRealm == null || pointOfInterestList == null || pointOfInterestList.isEmpty()) { 
     return; 
    } 

    mRealm.executeTransaction(new Realm.Transaction() { // <= line 155, java.lang.NullPointerException points to this line 
     @Override 
     public void execute(Realm realm) { 
      realm.insertOrUpdate(pointOfInterestList); 
     } 
    }); 
} 

我写了一个junit测试来测试它。

@RunWith(RobolectricTestRunner.class) 
@Config(constants = BuildConfig.class, sdk = 19) 
@PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "android.*"}) 
@SuppressStaticInitializationFor("io.realm.internal.Util") 
@PrepareForTest({Realm.class, RealmLog.class}) 
public class RealmPOIManagerTest 
{ 

    @Rule 
    public PowerMockRule rule = new PowerMockRule(); 
    private Realm mockRealm; 

    @Before 
    public void setUp() throws Exception 
    { 
     mockStatic(RealmLog.class); 
     mockStatic(Realm.class); 

     Realm mockRealm = PowerMockito.mock(Realm.class); 
     when(Realm.getDefaultInstance()).thenReturn(mockRealm); 

     this.mockRealm = mockRealm; 
    } 

    @Test 
    public void shouldVerifyThatPOIWasCreated() { 
     List<PointOfInterest> poiList = new ArrayList<>(1); 

     doCallRealMethod().when(mockRealm).executeTransaction(Mockito.any(Realm.Transaction.class)); 

     PointOfInterest pointOfInterest = mock(PointOfInterest.class); 
     when(mockRealm.createObject(PointOfInterest.class)).thenReturn(pointOfInterest); 

     poiList.add(pointOfInterest); 
     RealmPOIManager.getInstance().save(poiList); 

     // Verify that Realm#createObject was called only once and 
     // Verify that a PointOfInterest was in fact created. 
     verify(mockRealm, times(1)).insertOrUpdate(poiList); 
    } 

    @Test 
    public void shouldVerifyCRUD() 
    { 
     List<PointOfInterest> poiList = getCollectionOfPOIs(); 

     // Create list elements 
     RealmPOIManager.getInstance().save(poiList); // <= line 112 

     // Read a POI item from db based on id 
     PointOfInterest result = RealmPOIManager.getInstance().loadPOIByBookingId("1"); 

     // Make sure retrieved POI is as same as the original item 
     assertThat(poiList.get(0), is(result)); 

     // Update POI, save it and make sure the item has been updated 
     result.setUid("4"); 
     List<PointOfInterest> list = new ArrayList<>(1); 
     list.add(result); 
     RealmPOIManager.getInstance().save(list); 
     PointOfInterest result2 = RealmPOIManager.getInstance().loadPOIByBookingId("4"); 
     assertThat(result, is(result2)); 
     PointOfInterest result3 = RealmPOIManager.getInstance().loadPOIByBookingId("1"); 
     assertNull(result3); 
    } 

    private List<PointOfInterest> getCollectionOfPOIs() 
    { 
     List<PointOfInterest> poiList = new ArrayList<>(3); 

     PointOfInterest poi1 = new PointOfInterest(); 
     poi1.setUid("1"); 

     PointOfInterest poi2 = new PointOfInterest(); 
     poi2.setUid("2"); 

     PointOfInterest poi3 = new PointOfInterest(); 
     poi3.setUid("3"); 

     poiList.add(poi1); 
     poiList.add(poi2); 
     poiList.add(poi3); 

     return poiList; 
    } 
} 

第一次测试shouldVerifyThatPOIWasCreated成功通过,第二次失败。这是什么在日志中看到:

java.lang.NullPointerException 
    at io.realm.BaseRealm.beginTransaction(BaseRealm.java:337) 
    at io.realm.Realm.beginTransaction(Realm.java:122) 
    at io.realm.Realm.executeTransaction(Realm.java:1087) 
    at com.my.package.db.dao.RealmPOIManager.save(RealmPOIManager.java:155) 
    at com.my.package.sdk.db.dao.RealmPOIManagerTest.shouldVerifyCRUD(RealmPOIManagerTest.java:112) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) 
    at org.powermock.modules.junit4.rule.PowerMockStatement$1.run(PowerMockRule.java:65) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.powermock.reflect.internal.WhiteboxImpl.performMethodInvocation(WhiteboxImpl.java:1873) 
    at org.powermock.reflect.internal.WhiteboxImpl.doInvokeMethod(WhiteboxImpl.java:773) 
    at org.powermock.reflect.internal.WhiteboxImpl.invokeMethod(WhiteboxImpl.java:638) 
    at org.powermock.reflect.Whitebox.invokeMethod(Whitebox.java:401) 
    at org.powermock.classloading.ClassloaderExecutor.execute(ClassloaderExecutor.java:98) 
    at org.powermock.classloading.ClassloaderExecutor.execute(ClassloaderExecutor.java:78) 
    at org.powermock.modules.junit4.rule.PowerMockStatement.evaluate(PowerMockRule.java:57) 
    at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:251) 
    at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:188) 
    at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:54) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
    at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:152) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137) 
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:119) 
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42) 
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234) 
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) 


Process finished with exit code 255 

任何想法,将不胜感激。谢谢。

更新

这是我的PointOfInterest类的一部分。

@Parcel 
@RealmClass 
public class PointOfInterest implements RealmModel { 
    public static final String REALM_KEY_UID = "uid"; 

    @Required // Throw exception if BookingId is `null` 
    @PrimaryKey 
    String uid; 

... 
} 

回答

1

境界不工作的单元测试。 Realm的github上的单元测试示例显示Realm被嘲笑,因为Realm不能在Android之外工作。

要测试特定于领域的行为,您需要使用仪器测试。

(这基本上意味着,

doCallRealMethod().when(mockRealm).executeTransaction(Mockito.any(Realm.Transaction.class)); 

这将无法正常工作,被称为在非Android JVM背景下真正的方法将失败。)

+0

雅,我刚才听到来自Realm的那个人,谢谢 – Hesam

0

您需要再次进行取List<PointOfInterest> pointOfInterestListpublic void execute(Realm realm)

mRealm.executeTransaction(new Realm.Transaction() { // <= line 155, java.lang.NullPointerException points to this line 
    @Override 
    public void execute(Realm realm) { 

     // fetch objects 
     List<PointOfInterest> poiList = realm.where..... 

     realm.insertOrUpdate(poiList); 
    } 
}); 

https://realm.io/news/threading-deep-dive/

+0

感谢您的样品,我不知道我应该先拿它,我甚至没有找到类似的方法,当我看样品/测试:(请让我多搜索一次,我可以让你的想法进入工作,然后我会接受你的答案。谢谢 – Hesam