繁体   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