I'm trying to write a unittest that tests a cancellation of a Retrofit call, but I'm stuck.
Here's the implementation:
public class LoginInteractorImpl extends AbstractInteractor implements LoginInteractor {
private volatile Call<ResponseBody> mCall;
private UserRepo mUserRepository;
@Inject
public LoginInteractorImpl(WorkerThread workerThread, MainThread mainThread, UserRepo userRepository) {
super(workerThread,mainThread);
this.mUserRepository = userRepository;
}
@Override
public void login(final String username, final String password, final OnLoginFinishedListener listener) {
mWorkerThread.execute(new Runnable() {
@Override
public void run() {
mCall = mUserRepository.doLogin(Credentials.basic(username, password));
enqueue(new LoginCallbackImpl(mWorkerThread, mMainThread, listener));
}
});
}
@Override
public void cancel() {
if(mCall != null) {
mCall.cancel();
}
}
void enqueue(LoginCallback callback){
mCall.enqueue(callback);
}
}
Here's what I've got so far in my testclass:
public class LoginInteractorTest {
private LoginInteractorImpl mLoginInteractor;
@Mock
UserRepo mockUserRepository;
@Mock
private Call<ResponseBody> mockCall;
@Mock
private LoginInteractor.OnLoginFinishedListener mockLoginListener;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mLoginInteractor = new LoginInteractorImpl(new FakeWorkerThread(), new FakeMainThread(), mockUserRepository);
}
...
@Test
public void shouldCancelLoginCall() throws Exception {
final String username = "test";
final String password = "testtest";
LoginInteractorImpl spy = Mockito.spy(mLoginInteractor);
when(mockUserRepository.doLogin(anyString()))
.thenReturn(mockCall);
final CountDownLatch latch = new CountDownLatch(1);
// Somehow delay the call and cancel it instead?
when(mLoginInteractor.enqueue(any(LoginCallback.class)))
.thenAnswer(
// Somehow pospone the call from executing
);
// Enqueue logincall
mLoginInteractor.login(username, password, mockLoginListener);
// Cancel call
mLoginInteractor.cancel();
// Verify that cancel was called
verify(mockCall, times(1)).cancel();
}
}
My question is how can I stop the mockCall from being executed and verify that I've succeeded in doing my cancelation? My best bet is that I somehow have to use CountDownLatch, but I've never used it before and haven't been able to find and answer anywhere on how to use it in my usecase.