@Mock WorkItem;
@Test(timeOut = 300000)
public void testSomething() throws Exception {
<do some testing>
verifyWorkDone()
}
public void verifyWorkDone() {
ArgumentCaptor<WorkItemQuery> captor =
ArgumentCaptor.forClass(WorkItemQuery.class);
verify(WorkItem, atLeastOnce()).call(captor.capture());
}
Я хочу изменить приведенный выше блок кода для verifyWorkDone(), чтобы он продолжал повторять попытки проверки, пока не истечет время теста.
есть ли хороший способ сделать это? просто бросить цикл while?




Тестирование асинхронного поведения обычно не должно включать в себя опрос для проверки того, что что-то произошло как часть тестового поведения. Я предлагаю изолировать компонент, который будет работать асинхронно, и протестировать его отдельно, «в обычном режиме». Затем протестируйте компонент, который будет ждать на асинхронном компоненте, смоделировав асинхронный компонент на wait фиксированное количество времени, прежде чем ответить. Вы можете использовать это для тестирования ожидающего компонента во всех соответствующих случаях: ответ приходит, как и ожидалось, ответ приходит, но это ошибка, ответ никогда не приходит до истечения времени ожидания и т. д.
Например.
public interface AsyncObject {
public void invoke();
public Object check();
}
public class MyMockAsyncObject implements AsyncObject {
private long delay;
private long startTimeMillis;
public MyMockAsyncObject(long delay) {
this.delay = delay;
}
public void invoke() {
startTimeMillis = now();
}
public Object check() {
if (now() - startTimeMillis > delay) {
return new Object();
} else {
return null;
}
}
}
public class Waiter {
public AsyncObject myAsyncObject;
public Waiter(AsyncObject async) {
this.myAsyncObject = async;
}
public Object getResult() {
myAsyncObject.invoke();
return this.waitForResult();
}
private Object waitForResult() {
while(// is not timed out) {
// wait a while
myAsyncObject.check();
// return result if it's there
}
throw new Exception();
}
}
Вы бы передали ожидающему компоненту макет асинхронного компонента. Этот макет может содержать логику для ожидания фиксированного количества времени, прежде чем сделать ответ доступным. Что касается ненадежности, проверенная временем стратегия состоит в том, чтобы сделать время ожидания макета значительно меньшим, чем время ожидания компонента ожидания для «успешного» теста и значительно больше для «неудачного» теста. В мире современных процессоров разницы в пару секунд вполне достаточно. В любом случае поведение макета будет гораздо менее шатким, чем поведение настоящего асинхронного компонента.
Я понимаю макет, содержащий ожидание фиксированного времени. Я спрашиваю, что делает тестовый пример (тестируемый компонент), пока макет выполняет фиксированное время ожидания? это похоже на блокировку ответа?
Это фактический логический компонент, который ожидает так же, как и в продакшене, просто ожидание происходит в фиктивном компоненте, который ждет своего времени перед возвратом, а не в реальном асинхронном процессе. Итак, если ваше обычное поведение ожидания - «опрашивать каждые X секунд до истечения времени ожидания», оно будет делать это, и макет вернет ответ только после того, как он закончит ожидание. Если это «в тайм-аут, проверьте, есть ли ответ», он сделает это, и макет вернет ответ, только если он уже закончил ожидание.
так что же имитирует ожидание в тестовом примере ожидающего компонента? просто сон? что, если тест ненадежный или машина, на которой выполняется тест, загружена так, что это занимает больше времени, чем ожидаемое время ожидания?