单元测试取消改造调用
Unittesting the cancellation of a retrofit call
我正在尝试编写一个单元测试来测试 Retrofit 调用的取消,但我卡住了。
实现如下:
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);
}
}
这是我目前在测试课上得到的:
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();
}
}
我的问题是如何停止执行 mockCall 并验证我是否已成功取消?我最好的选择是我必须以某种方式使用 CountDownLatch,但我以前从未使用过它,并且无法在任何地方找到并回答如何在我的用例中使用它。
自己找到答案:
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();
}
我正在尝试编写一个单元测试来测试 Retrofit 调用的取消,但我卡住了。
实现如下:
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);
}
}
这是我目前在测试课上得到的:
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();
}
}
我的问题是如何停止执行 mockCall 并验证我是否已成功取消?我最好的选择是我必须以某种方式使用 CountDownLatch,但我以前从未使用过它,并且无法在任何地方找到并回答如何在我的用例中使用它。
自己找到答案:
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();
}