简体   繁体   English

Android:我如何对 Rxjava Observable 进行单元测试?

[英]Android: How can i unit test Rxjava Observable?

I'm studying android unit testing and i'm a bit stuck of unit testing for rxjava observable.我正在研究 android 单元测试,我对 rxjava observable 的单元测试有点卡住了。

This method i'm trying to test:我正在尝试测试的这种方法:

    @Override
    public Observable<AuthenticationUsingSqlEntity> logInUsingSql(String token, String ssid) {
        SqlRepo sqlRepo = new SqlRepo();
        return sqlRepo.authenticate(token, ssid);
    }

I have created simple ArgumentCaptor to test that input already the same and have been passed on unit testing what i'm trying to do is to test sql retrofit response but i can't.我创建了简单的 ArgumentCaptor 来测试已经相同的输入并且已经通过单元测试我想要做的是测试 sql retrofit 响应,但我不能。

I wonder why you provide some method call, but not the actual SqlRepo method to test?我想知道为什么你提供了一些方法调用,而不是实际的SqlRepo方法来测试? The result is, that this only permits for a general answer.结果是,这只允许一个一般的答案。 And it's unclear, which version you're talking about;目前还不清楚,你说的是哪个版本; I'd assume version 2. However, one can simply chain Observable with .test() , in order to test the Observable itself and there's TestObserver , but there's also TestSubscriber , which can be used to test subscribers and TestScheduler , which can be used to schedule mock RX events.我假设是版本 2。但是,可以简单地将Observable.test()链接,以测试Observable本身并且有TestObserver ,但也有TestSubscriber ,可用于测试订阅者和TestScheduler ,可用于安排模拟 RX 事件。 It should be obvious, that the method call which've provided will not suffice to write a proper test, as the method to test is entirely unknown (to me).很明显,提供的方法调用不足以编写正确的测试,因为测试的方法是完全未知的(对我来说)。

In your test on that method, you shouldn't use ArgumentCaptor.在您对该方法的测试中,您不应该使用 ArgumentCaptor。 Normally, it is used when you need to write a test on a method which receives or creates an object and you want to check the validity of that object as a parameter (for example, that an email address is formatted correctly).通常,当您需要对接收或创建 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);

The only test on that method that you can use is a test that checks if the method calls sqlRepo.authenticate.您可以使用的对该方法的唯一测试是检查该方法是否调用 sqlRepo.authenticate 的测试。 If you want to check the response from Retrofit, then you need to write a test specifically on the method 'authenticate' in the class SqlRepo.如果要查看 Retrofit 的响应,则需要专门针对 class SqlRepo 中的方法 'authenticate' 编写测试。 Also, if you want to write a test specifically on Observable, then you can use TestObserver.此外,如果您想专门针对 Observable 编写测试,则可以使用 TestObserver。 You can then use various methods to check the result you'll receive.然后,您可以使用各种方法来检查您将收到的结果。

Here's an example:这是一个例子:

someService.authenticate()
.test()
.assertNoErrors()
.assertValue( someValue -> 
//check if the value is correct
);

Assuming your class is similar to following:假设您的 class 类似于以下内容:

class LoginManager {

 @Override
    public Observable<AuthenticationUsingSqlEntity> logInUsingSql(String token, String ssid) {
        SqlRepo sqlRepo = new SqlRepo();
        return sqlRepo.authenticate(token, ssid);
    }
}

then with unit testing we are aiming to verify the logic of a unit or function.然后通过单元测试,我们旨在验证单元或 function 的逻辑。

in that perspective the logic of your method is that you we offload the login operation to SqlRepo class.从这个角度来看,您的方法的逻辑是您我们将登录操作卸载到 SqlRepo class。 And we have to verify this logic.我们必须验证这个逻辑。 So as to do that we check whether authenticate function of Sqlrepo is being invoked in response to the invokation of logInUsingSql() method.为此,我们检查是否正在调用 Sqlrepo 的验证 function 以响应 logInUsingSql() 方法的调用。 we do that by:我们这样做:

 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());

As you can see that LoginManager is dependent on SqlRepo class and we have to provide a mock for this dependency so that we ensure that test is carried out in isolation.如您所见,LoginManager 依赖于 SqlRepo class,我们必须为该依赖项提供一个模拟,以便我们确保单独执行测试。 so change Loginmanager Function to:所以将 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.

相关问题 RxJava:如何单元测试 Observable 在正确的调度程序上被观察和订阅? - RxJava: How to unit test that an Observable is observed on and subscribed on the right scheduler? 如何在单元测试中处理模拟的 RxJava2 可观察抛出异常 - How to handle mocked RxJava2 observable throwing exception in unit test 如何单元测试多线程Android RxJava - How unit test multithreaded Android RxJava 单元测试:如何在Android中的RxJava中验证和模拟onCompleted for Observable - Unit Testing: How to verify and mock onCompleted for an Observable in RxJava within Android 使用rxjava进行Android单元测试 - Unit test android application with rxjava Android单元测试如何测试observable和Subscriber - Android unit testing how to test observable and Subscriber Android:单元测试:如何使用SensorManager创建单元测试? - Android: Unit Test: How can I create unit test with SensorManager? 使用 RXJava 的 Android,如何将 Observable 与整数列表结合并将其转换为对象列表 - Android using RXJava, How can I take an Observable with a list of integers and turn it into a list of ojects 如何对RxJava重试单元测试 - How to unit test RxJava retryWhen 如何在Android上对RxJava Completable.error进行单元测试 - How to unit test RxJava Completable.error on Android
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM