[英]RxJava: How to unit test that an Observable is observed on and subscribed on the right scheduler?
[英]Android: How can i unit test Rxjava Observable?
我正在研究 android 單元測試,我對 rxjava observable 的單元測試有點卡住了。
我正在嘗試測試的這種方法:
@Override
public Observable<AuthenticationUsingSqlEntity> logInUsingSql(String token, String ssid) {
SqlRepo sqlRepo = new SqlRepo();
return sqlRepo.authenticate(token, ssid);
}
我創建了簡單的 ArgumentCaptor 來測試已經相同的輸入並且已經通過單元測試我想要做的是測試 sql retrofit 響應,但我不能。
我想知道為什么你提供了一些方法調用,而不是實際的SqlRepo
方法來測試? 結果是,這只允許一個一般的答案。 目前還不清楚,你說的是哪個版本; 我假設是版本 2。但是,可以簡單地將Observable
與.test()
鏈接,以測試Observable
本身並且有TestObserver
,但也有TestSubscriber
,可用於測試訂閱者和TestScheduler
,可用於安排模擬 RX 事件。 很明顯,提供的方法調用不足以編寫正確的測試,因為測試的方法是完全未知的(對我來說)。
在您對該方法的測試中,您不應該使用 ArgumentCaptor。 通常,當您需要對接收或創建 object 的方法編寫測試並且您想檢查該 object 作為參數的有效性(例如,email 地址的格式是否正確)時使用。
// Create a mock of the OtherClass
OtherClass other = mock(OtherClass.class);
// Run the foo method with the mock
new A().foo(other);
// Capture the argument of the doSomething function
ArgumentCaptor<SomeData> captor = ArgumentCaptor.forClass(SomeData.class);
verify(other, times(1)).doSomething(captor.capture());
// Assert the argument
SomeData actual = captor.getValue();
assertEquals("Some inner data", actual.innerData);
您可以使用的對該方法的唯一測試是檢查該方法是否調用 sqlRepo.authenticate 的測試。 如果要查看 Retrofit 的響應,則需要專門針對 class SqlRepo 中的方法 'authenticate' 編寫測試。 此外,如果您想專門針對 Observable 編寫測試,則可以使用 TestObserver。 然后,您可以使用各種方法來檢查您將收到的結果。
這是一個例子:
someService.authenticate()
.test()
.assertNoErrors()
.assertValue( someValue ->
//check if the value is correct
);
假設您的 class 類似於以下內容:
class LoginManager {
@Override
public Observable<AuthenticationUsingSqlEntity> logInUsingSql(String token, String ssid) {
SqlRepo sqlRepo = new SqlRepo();
return sqlRepo.authenticate(token, ssid);
}
}
然后通過單元測試,我們旨在驗證單元或 function 的邏輯。
從這個角度來看,您的方法的邏輯是您我們將登錄操作卸載到 SqlRepo class。 我們必須驗證這個邏輯。 為此,我們檢查是否正在調用 Sqlrepo 的驗證 function 以響應 logInUsingSql() 方法的調用。 我們這樣做:
loginManagerClassUnderTest = Mockito.spy(loginManagerClassUnderTest);
mockSqlRepo mockSqlRepo = Mockito.mock(mockSqlRepo.class);
doReturn(mockSqlRepo).when(loginManagerClassUnderTest).getSqlRepo();
loginManagerClassUnderTest.logInUsingsql("mockToken", "mockSsid");
ArgumentCaptor<String> tokenCaptor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<String> ssidCaptor = ArgumentCaptor.forClass(String.class);
verify(mockSqlRepo).authenticate(tokenCaptor.capture(), ssidCaptor.capture());
assertEquals("mockToken", tokenCaptor.getValue());
assertEquals("mockSsid", ssidCaptor.getValue());
如您所見,LoginManager 依賴於 SqlRepo class,我們必須為該依賴項提供一個模擬,以便我們確保單獨執行測試。 所以將 Loginmanager Function 更改為:
class LoginManager {
@Override
public Observable<AuthenticationUsingSqlEntity> logInUsingSql(String token, String ssid) {
SqlRepo sqlRepo = getSqlRepo();
return sqlRepo.authenticate(token, ssid);
}
public SqlRepo getSqlRepo() {
return new SqlRepo();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.