简体   繁体   中英

Presenter unit test with RxJava CompositeSubscription

I would like to create a test for my Presenter class but I'm having problems with the CompositeSubscription instance inside the Presenter itself. When I run the test I'm getting this error:

java.lang.NullPointerException
at rx.subscriptions.CompositeSubscription.add(CompositeSubscription.java:60)
at com.example.Presenter.addSubscription(Presenter.java:67)
at com.example.Presenter.getGummyBears(Presenter.java:62)

This is roughly my Presenter class:

public class Presenter {

    CompositeSubscription compositeSubscription = new CompositeSubscription();
    //creation methods...

    public void addSubscription(Subscription subscription) {
       if (compositeSubscription == null || compositeSubscription.isUnsubscribed()) {
           compositeSubscription = new CompositeSubscription();
         }
       compositeSubscription.add(subscription);
    }

    public void getGummyBears() {
        addSubscription(coreModule.getGummyBears());
    }
}

The CoreModule is an interface (part of a different module) and there is another class CoreModuleImpl in which are located all retrofit API calls and their conversion to Subscriptions. Something like:

@Override public Subscription getGummyBears() {
  Observable<GummyBears> observable = api.getGummyBears();
  //a bunch of flatMap, map and other RxJava methods
  return observable.subscribe(getDefaultSubscriber(GummyBear.class));

  //FYI the getDefaultSubscriber method posts a GummyBear event on EventBus
}

Now what I want to do is to test the getGummyBears() method. My test method looks like this:

@Mock EventBus eventBus;
@Mock CoreModule coreModule;
@InjectMock CoreModuleImpl coreModuleImpl;

private Presenter presenter;

@Before
public void setUp() {
  presenter = new Presenter(coreModule, eventBus);
  coreModuleImpl = new CoreModuleImpl(...);
}


@Test
public void testGetGummyBears() {
  List<GummyBears> gummyBears = MockBuilder.newGummyBearList(30);

  //I don't know how to set correctly the coreModule subscription and I'm trying to debug the whole CoreModuleImpl but there are too much stuff to Mock and I always end to the NullPointerException

  presenter.getGummyBears(); //I'm getting the "null subscription" error here
  gummyBears.setCode(200);

  presenter.onEventMainThread(gummyBears);
  verify(gummyBearsView).setGummyBears(gummyBears);
}

I already saw many test examples from different projects but no one is using this Subscription approach. They just return the Observable which is consumed directly inside the presenter. And in that case I know how a test has to be written.

What's the correct way to test my situation?

Looks like coreModule.getGummyBears() is returning null. Just step through with debug and it should be pretty clear. When using mocking frameworks you can get null returned from method calls on a mocked object when you haven't specified what the method call should return on that mocked object.

As Dave mentioned, you need to mock the return value of CoreModule.getGummyBears . One strange thing is that you are not using the CoreModuleImpl that is being created. Instead, you're passing coreModule to the presenter's constructor.

You can mock getGummyBears() by doing something like this:

when(coreModule.getGummyBears()).thenReturn(MockBuilder.newGummyBearList(30);

Then the specific error you are encountering should be resolved. It doesn't look like you need CoreModuleImpl for this specific test case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM