I am using MVVM pattern with databinding. I have written tests. But I want them reviewed. The test is related to JUnit
test on the ViewModel.
FeedViewModelTest.java
@RunWith(PowerMockRunner.class)
@PrepareForTest({Observable.class, AndroidSchedulers.class})
@PowerMockIgnore("javax.net.ssl.*")
public class FeedViewModelTest {
FeedViewModel feedViewModel;
DataManager dataManager;
FeedViewModel.DataListener dataListener;
FeedApi feedApi;
@Before
public void setUp() {
dataListener = mock(FeedViewModel.DataListener.class);
Context mMockContext = mock(Context.class);
dataManager =mock(DataManager.class);
feedApi = mock(FeedApi.class);
feedViewModel = spy(new FeedViewModel(mMockContext, dataListener));
}
@Test
public void testShouldScheduleLoadFromAPIOnBackgroundThread() {
Observable<FeedResponse> observable = (Observable<FeedResponse>) mock(Observable.class);
when(dataManager.fetchFeed()).thenReturn(observable);
when(observable.subscribeOn(Schedulers.io())).thenReturn(observable);
when(observable.observeOn(AndroidSchedulers.mainThread())).thenReturn(observable);
//call test method
feedViewModel.fetchFeed();
verify(feedViewModel).fetchFeed();
TestSubscriber<FeedResponse> testSubscriber = new TestSubscriber<>();
observable.subscribeOn(Schedulers.io());
observable.observeOn(AndroidSchedulers.mainThread());
observable.subscribeWith(new DisposableObserver<FeedResponse>() {
@Override
public void onNext(FeedResponse value) {
dataListener.onDataChanged(value.getData());
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
dataListener.onError();
}
@Override
public void onComplete() {
}
});
//verify if all methods in the chain are called with correct arguments
verify(observable).subscribeOn(Schedulers.io());
verify(observable).observeOn(AndroidSchedulers.mainThread());
verify(observable).subscribeWith(Matchers.<DisposableObserver<FeedResponse>>any());
}
}
FeedViewModel.java
public class FeedViewModel {
public DataManager dataManager;
private DataListener datalistener;
private Context mContext;
public FeedViewModel(Context context, DataListener datalistener) {
this.datalistener = datalistener;
mContext = context;
dataManager = new DataManager();
}
public void fetchFeed() {
dataManager.fetchFeed()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableObserver<FeedResponse>() {
@Override
public void onError(Throwable e) {
e.printStackTrace();
datalistener.onError();
}
@Override
public void onComplete() {
}
@Override
public void onNext(FeedResponse feedResponse) {
if(datalistener!=null) {
datalistener.onDataChanged(feedResponse.getData());
}
}
});
}
public interface DataListener
{
void onDataChanged(List<FeedModel> model);
void onError();
}
}
DataManager.java
public class DataManager {
private FeedApi feedApi;
private Observable<FeedResponse> feedResponseObservable;
public FeedApi getFeedApi() {
return feedApi;
}
public DataManager()
{
feedApi = new FeedApi();
}
public Observable<FeedResponse> fetchFeed() {
feedResponseObservable = feedApi.fetchFeed(1);
return feedResponseObservable;
}
}
Testing libs used:
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.9.5'
testCompile 'org.powermock:powermock-api-mockito:1.5.6'
testCompile 'org.powermock:powermock-module-junit4:1.6.2'
DataListener
is an interface and is used as a callback to the activity. I have some views in activity that are visible or gone based on the data fetched from the server. Is my unit test for FeedViewModel correct?
Note: The test for FeedViewModelTest passes. I am using the RxJava2.