#java #unit-testing #service #callback
#java #модульное тестирование #Обслуживание #обратный вызов
Вопрос:
Ниже приведен класс, который я хочу протестировать: SomeClass.java
public void SomeClass {
final CountDownLatch latch = new CountDownLatch(1);
int resu<
registerCallbackWithService(new MyCallback());
public int callToExternalService(){
//Do some stuff and make service call
latch.await();
return resu<
}
class MyCallback implements ServiceCallback {
@Override
public void onResult(final int res) {
//do something
result = res;
latch.countdown();
}
}
}
Обратный вызов MyCallback
был зарегистрирован ранее перед вызовом callToExternalService()
.
Если я напишу простой тест, чтобы просто имитировать вызов службы, выполненный в callToExternalService()
, тест будет выполняться бесконечно из-за latch.await()
.
Как я могу протестировать логику в callToExternalService()
, а также в onResult()
?
Ответ №1:
Я изменил код, чтобы отобразить обратный вызов, который я регистрирую, используя функцию, защищенную пакетом, как показано ниже :
public void SomeClass {
private final CountDownLatch latch = new CountDownLatch(1);
private int resu<
registerCallback(new MyCallback());
public int callToExternalService(){
//Do some stuff and make service call
latch.await();
return resu<
}
private class MyCallback implements ServiceCallback {
@Override
public void onResult(final int res) {
//do something
result = res;
latch.countdown();
}
}
protected registerCallback(ServiceCallback callback) {
registerCallbackWithService(callback);
}
}
Теперь для тестирования я провожу тестирование, создавая новый класс SomeClassTest extends SomeClass
и используя экземпляр этого класса. SomeClassTest
Все, что я делаю, это переопределяю registerCallback()
для доступа к регистрируемому экземпляру обратного вызова.
public class ServiceTest {
private ServiceCallback mServiceCallback;
class SomeClassTest extends SomeClass {
@Override
registerCallback(ServiceCallback callback) {
mServiceCallback = callback;
super.registerCallback(callback);
}
}
}
Теперь все, что мне нужно сделать с помощью doAnswer
обратного вызова при запросе службы, который приводит к выполнению latch.countdown()
по той же latch
ссылке, которая вводится await
сразу после выполнения запроса службы.
SomeClassTest someClassInstance = new SomeClassTest();
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
mServiceVCallback.onResult(int_I_want_to_test_for)
return null;
}
}).when(someClassInstance).service_request_before_latch_await();
int response = someClassInstance.callToExternalService();
assertEquals(response, expected_response);