使用Retrofit进行RxJava JUnit测试会抛出NullPointerException

时间:2017-02-22 06:37:34

标签: android unit-testing junit retrofit2 rx-java2

我有一个retrofit2 API调用

public interface FeedService {
    @GET("/api/v1/feeds")
    Observable<FeedResponse> getFeeds(@Query("page") Integer pageNumber,
                                          @Query("cats") String categories,
                                          @Query("lang") String language);
}

我有一个使用此API的Repository -

public class FeedRepositoryImpl implements FeedRepository {
    private static FeedRepositoryImpl INSTANCE;
    private int FIRST_PAGE = 1;
    private FeedService feedService;

    public static FeedRepositoryImpl getFeedRepository(FeedService feedService) {
        if (INSTANCE == null) {
            INSTANCE = new FeedRepositoryImpl(feedService);
        }
        return INSTANCE;
    }

    @Override
    public Observable<Feed> getFeeds(final int pageNumber, final String categories, final String
            language) {
        return feedService.getFeeds(pageNumber, categories, language)
                .concatMap(new Function<FeedResponse, ObservableSource<? extends Feed>>() {
                    @Override
                    public ObservableSource<? extends Feed> apply(FeedResponse feedResponse) throws
                            Exception {
                        return Observable.fromIterable(feedResponse.feedsData());
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
    }
}

现在,我正在尝试编写JUnit测试,以验证是否使用用于调用FeedService's的相同参数调用getFeeds() FeedRepository.getFeeds()

但是,我得到NullPointerException。这是我的测试的样子 -

public class FeedRepositoryImplTest {

    private static String CATEGORIES = "feeds?page=1&cats=top,yt,world,ent,ls,sp";
    private static String LANGUAGE = "lang=en";
    private static int PAGE_NUMBER = 1;

    @Rule
    public ImmediateSchedulersRule immediateSchedulersRule = new ImmediateSchedulersRule();
    @Mock
    FeedService feedService;
    FeedRepositoryImpl feedRepository;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        feedRepository = FeedRepositoryImpl.getFeedRepository(feedService);
    }

    @Test
    public void getFeeds() throws Exception {
        // arrange
        Observable<Feed> emptyFeed = Observable.empty();
        when(feedRepository.getFeed(PAGE_NUMBER, CATEGORIES, LANGUAGE))
                .thenReturn(emptyFeed);

        // act
        feedRepository.getFeed(PAGE_NUMBER, CATEGORIES, LANGUAGE);

        System.out.println("feedRepository.getFeeds(PAGE_NUMBER, CATEGORIES, LANGUAGE)");
        // assert
        verify(feedService).getFeeds(PAGE_NUMBER, CATEGORIES, LANGUAGE);
    }
}

我的TestRule看起来像这样 -

public class ImmediateSchedulersRule implements TestRule {
    @Override
    public Statement apply(final Statement base, Description description) {
        return () -> {
                RxJavaPlugins.setIoSchedulerHandler((scheduler) -> {
                        return Schedulers.trampoline();
                });
                RxJavaPlugins.setComputationSchedulerHandler((scheduler) -> {
                        return Schedulers.trampoline();
                });
                RxJavaPlugins.setNewThreadSchedulerHandler((scheduler) -> {
                        return Schedulers.trampoline();
                });
                RxAndroidPlugins.setMainThreadSchedulerHandler((scheduler) -> {
                        return Schedulers.trampoline();
                });
                RxAndroidPlugins.setInitMainThreadSchedulerHandler((schedulerCallable) -> {
                        return Schedulers.trampoline();
                });
                base.evaluate();
        };
    }
}

此行抛出异常 -

.concatMap(new Function<FeedResponse, ObservableSource<? extends Feed>>() { ... }

我做错了什么?

1 个答案:

答案 0 :(得分:2)

您正在尝试mock FoodRepositoryImpl这是一个真实对象的方法(使用模拟的feedService)。

变化:

feedRepository = FeedRepositoryImpl.getFeedRepository(feedService);

feedRepository = Mockito.spy(FeedRepositoryImpl.getFeedRepository(feedService));

编辑:

你应该将方法mock更改为(spying FeedRepositoryImpl无关紧要):

when(feedService.getFeeds(PAGE_NUMBER, CATEGORIES, LANGUAGE)).thenReturn(emptyFeed);