使用 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);
我有一个改造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);