我想測試我的視圖模型在我的應用程序,這裏是構造函數:驗證匿名內部類模擬互動
@Inject
public SearchUserViewModel(@Named("searchUser") UseCase searchUserUseCase) {
this.searchUserUseCase = searchUserUseCase;
}
在我的測試中,我創建這樣與嘲笑一個SearchUserUseCase:
Observable error = Observable.error(new Throwable("Error"));
when(gitHubService.searchUser(MockFactory.TEST_USERNAME_ERROR)).thenReturn(error);
when(ObserverThread.getScheduler()).thenReturn(Schedulers.immediate());
when(SubscriberThread.getScheduler()).thenReturn(Schedulers.immediate());
searchUserUseCase = new SearchUserUseCase(gitHubService, SubscriberThread, ObserverThread);
在我的ViewModel類我有這個片段,我想測試:
public void onClickSearch(View view) {
loadUsers();
}
private void loadUsers() {
if (username == null) {
fragmentListener.showMessage("Enter a username");
} else {
showProgressIndicator(true);
searchUserUseCase.execute(new SearchUserSubscriber(), username);
}
}
private final class SearchUserSubscriber extends DefaultSubscriber<SearchResponse> {
@Override
public void onCompleted() {
showProgressIndicator(false);
}
@Override
public void onError(Throwable e) {
showProgressIndicator(false);
fragmentListener.showMessage("Error loading users");
}
@Override
public void onNext(SearchResponse searchResponse) {
List<User> users = searchResponse.getUsers();
if (users.isEmpty()) {
fragmentListener.showMessage("No users found");
} else {
fragmentListener.addUsers(users);
}
}
}
最後,在我的測試中,我有這樣的:
@Test
public void shouldDisplayErrorMessageIfErrorWhenLoadingUsers() {
SearchUserViewModel searchUserViewModel = new SearchUserViewModel(searchUserUseCase);
searchUserViewModel.setFragmentListener(mockFragmentListener);
searchUserViewModel.setUsername(MockFactory.TEST_USERNAME_ERROR);
searchUserViewModel.onClickSearch(view);
verify(mockFragmentListener).showMessage("Error loading users");
}
我得到這個錯誤來自的Mockito:
Wanted but not invoked:
fragmentListener.showMessage(
"Error loading users"
);
我不知道這是否是一個很好的測試,但我有點想測試SearchUserSubscriber的一種方式或其他。謝謝
編輯:我發現這個問題類似的問題在這裏:Can't verify mock method call from RxJava Subscriber(仍然沒有回答)和在這裏:Verify interactions in rxjava subscribers。後一個問題是類似的,但不會在單獨的類中執行訂閱(這發生在SearchUserUseCase這裏)。
我也嘗試RobolectricGradleTestRunner而不是MockitoJunitRunner,並更改爲Schedulers.io()和AndroidSchedulers.mainThread(),但我仍然得到相同的錯誤。
嘗試嘲笑SearchUserUseCase而不是GitHubService(感覺更乾淨),但我不確定如何測試訂閱方式,因爲它作爲參數傳遞給void方法execute()在UseCase中。
public void execute(Subscriber useCaseSubscriber, String query) {
subscription = buildUseCase(query)
.observeOn(postExecutionThread.getScheduler())
.subscribeOn(threadExecutor.getScheduler())
.subscribe(useCaseSubscriber);
}
而且buildUseCase()
@Override
public Observable buildUseCase(String username) throws NullPointerException {
if (username == null) {
throw new NullPointerException("Query must not be null");
}
return getGitHubService().searchUser(username);
}
我不知道最初是什麼問題,但它現在正在一些重構來回工作。我最終得到的代碼與問題完全相同。 – hboy