使用 Retrofit 的 RxJava JUnit 测试抛出 NullPointerException

RxJava JUnit test with Retrofit throws a NullPointerException

我有一个改造API电话

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

我有一个使用这个 API 的存储库,就像这样-

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>>() { ... }

我做错了什么?

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

变化:

feedRepository = FeedRepositoryImpl.getFeedRepository(feedService);

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

编辑:

您应该将 mock 方法更改为(监视 FeedRepositoryImpl 无关紧要):

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