Unit Test - Verify Observable is subscribed

前端 未结 4 2099
攒了一身酷
攒了一身酷 2021-02-08 00:19

I have got the java code like this

 mDataManager.getObservable(\"hello\").subscribe( subscriber );

and I want to verify the follow

4条回答
  •  名媛妹妹
    2021-02-08 00:53

    I'm not certain I am answering the asked question, but I think so...

    Unit tests can be created that check whether a subscription has been made to an observable. Note that in RxJava 1.x, this was supported with TestSubject, but that functionality can be facilitated by Subject implementations. TestSubject was dropped for RxJava 2.

    Rather than attempting to mock the observable as the original poster is trying to do, use a PublishSubject, run the business logic, then use the publish subject to see if the Observable is being observed. Below is some test code that validates this testing is possible. The tests pass when I run them.

    See code comments for description of the code. Personally, this test seems redundant to other tests that would verify how the controller handles data. Those other tests would fail if the controller never subscribed to and received data from the data service. On the other hand, testing unsubscribe helps avoid memory leaks, which is probably high value.

    import org.junit.Test;
    
    import io.reactivex.Observable;
    import io.reactivex.disposables.Disposable;
    import io.reactivex.subjects.PublishSubject;
    
    import static junit.framework.Assert.assertFalse;
    import static junit.framework.Assert.assertTrue;
    
    /**
     * Tests whether it is possible to test whether a controller properly unsubscribes from an Observable.
     */
    public class SubscribeUnsubscribeTests {
    
        /**
         * A service that returns a stream of strings.
         */
        interface StringService {
            Observable getStrings();
        }
    
        /**
         * A controller that requests strings from the {@link StringService} and logs them
         * to system out as they are received.
         */
        class StringLoggingController {
    
            private StringService stringService;
    
            private Disposable stringSubscriptionDisposable;
    
            public StringLoggingController(StringService stringService) {
                this.stringService = stringService;
            }
    
            /**
             * Causese the controller to begin strings request and logging.
             */
            public void start() {
                stringSubscriptionDisposable = stringService.getStrings()
                        .subscribe(string -> System.out.print(string));
            }
    
            public void stop() {
                if (stringSubscriptionDisposable != null) {
                    if (!stringSubscriptionDisposable.isDisposed()) {
                        stringSubscriptionDisposable.dispose();
                        stringSubscriptionDisposable = null;
                    }
                }
            }
        }
    
        /**
         * A {@link StringService} that can report whether {@link StringService#getStrings()}
         * has observers.
         */
        class ReportIsSubscribedStringService implements StringService {
    
            private PublishSubject publishSubject = PublishSubject.create();
    
            public Observable getStrings() {
                return publishSubject;
            }
    
            /**
             * @return true if the {@link #getStrings()} observable has observers.
             */
            public boolean stringsAreBeingObserved() {
                return publishSubject.hasObservers();
            }
        }
    
        /**
         * Verifies that the {@link StringLoggingController} is subscribing to the service.
         */
        @Test
        public void stringsLoggingControllerSubscribesToStringService() {
            ReportIsSubscribedStringService service = new ReportIsSubscribedStringService();
            StringLoggingController controller = new StringLoggingController(service);
    
            controller.start();
            assertTrue(service.stringsAreBeingObserved());
        }
    
        /**
         * Verifies that the {@link StringLoggingController} is unsubscribing from the service.
         */
        @Test
        public void stringsLoggingControllerUnsubscribesFromStringService() {
            ReportIsSubscribedStringService service = new ReportIsSubscribedStringService();
            StringLoggingController controller = new StringLoggingController(service);
    
            controller.start();
            controller.stop();
    
            assertFalse(service.stringsAreBeingObserved());
        }
    }
    

    -- edit -- I previously wrote that I wasn't able to test for unsubscribe. I did figure out how to test that. It turns out my test was failing because the tested code wasn't properly unsubscribing (hah - testing works, go figure). I've updated the code above to illustrate testing both subscribe and unsubscribe.

提交回复
热议问题