2017-02-13 106 views
1

我想單元測試領域及其相互作用,但事情並不太順利。我已經包含了所有的依賴關係,並且一直得到模糊的失敗,下面是我的Helper類的代碼,它是Realm的封裝。領域單元測試

問題

  1. 這是測試領域的正確方法是什麼?

  2. 如何測試應用沙盒中的數據,只能通過UI/Instrumentation測試來測試該數據?

  3. 我目前(下同)得到一個錯誤,我得到一個前「Powermock零參數的構造不存在」

GitHub repo

下面是當前代碼我有我的單元測試:

@RunWith(PowerMockRunner.class) 
@PowerMockRunnerDelegate(RobolectricTestRunner.class) 
@Config(constants = BuildConfig.class, sdk = 21, application = CustomApplicationTest.class) 
@PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "android.*", "javax.crypto.","java.security.*"}) 
@SuppressStaticInitializationFor("io.realm.internal.Util") 
@PrepareForTest({Realm.class, RealmConfiguration.class, 
    RealmQuery.class, RealmResults.class, RealmCore.class, RealmLog.class}) 
public class DatabaseHelperTest { 

@Rule 
public PowerMockRule rule = new PowerMockRule(); 

private DatabaseHelper dB; 

private Realm realmMock; 


@Before 
public void setUp() throws Exception { 
    MockitoAnnotations.initMocks(this); 

    mockStatic(Realm.class); 
    mockStatic(RealmConfiguration.class); 
    mockStatic(RealmCore.class); 
    mock(DatabaseHelper.class); 

    final Realm mockRealm = PowerMockito.mock(Realm.class); 
    realmMock = mockRealm; 

    final RealmConfiguration mockRealmConfig = PowerMockito.mock(RealmConfiguration.class); 

    doNothing().when(RealmCore.class); 
    RealmCore.loadLibrary(any(Context.class)); 

    whenNew(RealmConfiguration.class).withAnyArguments().thenReturn(mockRealmConfig); 
    when(Realm.getInstance(any(RealmConfiguration.class))).thenReturn(mockRealm); 
    when(Realm.getDefaultInstance()).thenReturn(mockRealm); 

    when(Realm.getDefaultInstance()).thenReturn(realmMock); 

    when(realmMock.createObject(Person.class)).thenReturn(new Person()); 

    Person person = new Person(); 
    person.setId("2"); 
    person.setName("Jerry"); 
    person.setAge("25"); 

    Person person2 = new Person(); 
    person.setId("3"); 
    person.setName("Tom"); 
    person.setAge("22"); 

    List<Person> personsList = new ArrayList<>(); 
    personsList.add(person); 
    personsList.add(person2); 

    RealmQuery<Person> personRealmQuery = mockRealmQuery(); 
    when(realmMock.where(Person.class)).thenReturn(personRealmQuery); 

    RealmResults<Person> personRealmResults = mockRealmResults(); 
    when(realmMock.where(Person.class).findAll()).thenReturn(personRealmResults); 
    when(personRealmResults.iterator()).thenReturn(personsList.iterator()); 
    when(personRealmResults.size()).thenReturn(personsList.size()); 

    when(realmMock.copyFromRealm(personRealmResults)).thenReturn(personsList); 

    realmMock = mockRealm; 
    dB = new DatabaseHelper(realmMock); 
} 


@Test 
public void insertingPerson(){ 
    doCallRealMethod().when(realmMock).executeTransaction(any(Realm.Transaction.class)); 

    Person person = mock(Person.class); 
    when(realmMock.createObject(Person.class)).thenReturn(person); 

    dB.putPersonData(); 

    verify(realmMock, times(1)).createObject(Person.class); 
    verify(person, times(1)).setId(anyString()); 
} 


@Test 
public void testExistingData(){ 
    List<Person> personList = dB.getPersonList(); 
    //NPE if checking person object properties i.e name, id. Only list size is available why? 
    Assert.assertEquals(2, personList.size()); 

} 

@SuppressWarnings("unchecked") 
private <T extends RealmObject> RealmQuery<T> mockRealmQuery() { 
    return mock(RealmQuery.class); 
} 

@SuppressWarnings("unchecked") 
private <T extends RealmObject> RealmResults<T> mockRealmResults() { 
    return mock(RealmResults.class); 
} 

錯誤:

org.mockito.exceptions.misusing.NotAMockException: 
Argument passed to verify() is of type Realm$$EnhancerByMockitoWithCGLIB$$317bc746 and is not a mock! 
Make sure you place the parenthesis correctly! 
See the examples of correct verifications: 
verify(mock).someMethod(); 
verify(mock, times(10)).someMethod(); 
verify(mock, atLeastOnce()).someMethod(); 

at com.appstronomy.realmunittesting.db.DatabaseHelperTest.insertingPerson(DatabaseHelperTest.java:133) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
+0

與http://stackoverflow.com/questions/34343601/powermockito-notamockexception-on-a-mock同樣的問題。只要加入「org.powermock。*」的行@PowerMockIgnore ... – beeender

回答

0

https://medium.com/@q2ad/android-testing-realm-2dc1e1c94ee1有很大的建議:不要模仿境界,但使用臨時實例,而不是。原命題與依賴注入:使用

RealmConfiguration testConfig = 
    new RealmConfiguration.Builder(). 
     inMemory(). 
     name("test-realm").build(); 

Realm testRealm = Realm.getInstance(testConfig); 

If dependency injection is not possible, you could use

Realm.setDefaultConfiguration(testConfig); 

代替,這臺由Realm.getDefaultInstance()返回Realm


編輯:如果您收到java.lang.IllegalStateException,記得打電話Realm.init(InstrumentationRegistry.getTargetContext())提前。

+0

這是行不通的,因爲它拋出異常'java.lang.IllegalStateException:創建RealmConfiguration' –

+0

之前調用'Realm.init(上下文)'@VictorApoyan :當然,你需要設置。編輯有幫助嗎? –