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.
Found the answer myself:
public void shouldCancelLoginCall() throws Exception {
final String username = "test";
final String password = "testtest";
LoginInteractorImpl spy = Mockito.spy(mLoginInteractor);
when(mockUserRepository.doLogin(anyString())).thenReturn(mockCall);
doNothing().when(spy).enqueue(any(LoginCallback.class));
mLoginInteractor.login(username, password, mockLoginListener);
mLoginInteractor.cancel();
verify(mockCall, times(1)).cancel();
}