简体   繁体   English

使用RxJava CompositeSubscription进行Presenter单元测试

[英]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. 我想为我的Presenter类创建一个测试但是我在Presenter本身内部遇到了CompositeSubscription实例的问题。 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: 这大致是我的Presenter类:

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. CoreModule是一个接口(不同模块的一部分),还有另一个类CoreModuleImpl,其中包含所有改进API调用及其转换为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. 现在我想要做的是测试getGummyBears()方法。 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. 他们只返回直接在演示者内部消费的Observable。 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. 看起来coreModule.getGummyBears()返回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. 使用模拟框架时,如果未指定方法调用应在该模拟对象上返回的内容,则可以从模拟对象上的方法调用返回null。

As Dave mentioned, you need to mock the return value of CoreModule.getGummyBears . 正如Dave所说,你需要模拟CoreModule.getGummyBears的返回值。 One strange thing is that you are not using the CoreModuleImpl that is being created. 一个奇怪的事情是你没有使用正在创建的CoreModuleImpl Instead, you're passing coreModule to the presenter's constructor. 相反,您将coreModule传递给演示者的构造函数。

You can mock getGummyBears() by doing something like this: 您可以通过执行以下操作来模拟getGummyBears()

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. 对于此特定测试用例,您看起来不需要CoreModuleImpl

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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