我想为我的Presenter类创建一个测试,但是我在Presenter本身内部的compositessubscription实例中遇到了问题。当我运行测试时,我得到这个错误:
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)
这大概是我的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());
}
}
CoreModule是一个接口(不同模块的一部分),还有另一个类CoreModuleImpl,其中包含所有的改装API调用和它们到订阅的转换。比如:
@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
}
现在我要做的是测试getGummyBears()
方法。我的测试方法是这样的:
@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);
}
我已经看到了来自不同项目的许多测试示例,但没有人使用这种订阅方法。它们只是返回可观察对象,它会直接在演示器内部被使用。在这种情况下,我知道如何编写测试。
测试我的情况的正确方法是什么?
看起来coreModule.getGummyBears()
返回null。只要逐步调试,应该就很清楚了。当使用mock框架时,当您没有指定该方法调用应该在该模拟对象上返回什么时,您可以从对模拟对象的方法调用中获得null返回值。
正如Dave提到的,您需要模拟CoreModule.getGummyBears
的返回值。一个奇怪的事情是,您没有使用正在创建的CoreModuleImpl
。相反,您将把coreModule
传递给演示者的构造函数。
你可以模仿getGummyBears()
做这样的事情:
when(coreModule.getGummyBears()).thenReturn(MockBuilder.newGummyBearList(30);
那么您遇到的特定错误应该得到解决。对于这个特定的测试用例,看起来不需要CoreModuleImpl
。