簡體   English   中英

Android:我如何對 Rxjava Observable 進行單元測試?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM