Mockito: ожидание опроса при проверке

@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?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
307
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Тестирование асинхронного поведения обычно не должно включать в себя опрос для проверки того, что что-то произошло как часть тестового поведения. Я предлагаю изолировать компонент, который будет работать асинхронно, и протестировать его отдельно, «в обычном режиме». Затем протестируйте компонент, который будет ждать на асинхронном компоненте, смоделировав асинхронный компонент на 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();
    }
}

так что же имитирует ожидание в тестовом примере ожидающего компонента? просто сон? что, если тест ненадежный или машина, на которой выполняется тест, загружена так, что это занимает больше времени, чем ожидаемое время ожидания?

ealeon 25.06.2019 00:45

Вы бы передали ожидающему компоненту макет асинхронного компонента. Этот макет может содержать логику для ожидания фиксированного количества времени, прежде чем сделать ответ доступным. Что касается ненадежности, проверенная временем стратегия состоит в том, чтобы сделать время ожидания макета значительно меньшим, чем время ожидания компонента ожидания для «успешного» теста и значительно больше для «неудачного» теста. В мире современных процессоров разницы в пару секунд вполне достаточно. В любом случае поведение макета будет гораздо менее шатким, чем поведение настоящего асинхронного компонента.

MyStackRunnethOver 25.06.2019 00:49

Я понимаю макет, содержащий ожидание фиксированного времени. Я спрашиваю, что делает тестовый пример (тестируемый компонент), пока макет выполняет фиксированное время ожидания? это похоже на блокировку ответа?

ealeon 25.06.2019 00:54

Это фактический логический компонент, который ожидает так же, как и в продакшене, просто ожидание происходит в фиктивном компоненте, который ждет своего времени перед возвратом, а не в реальном асинхронном процессе. Итак, если ваше обычное поведение ожидания - «опрашивать каждые X секунд до истечения времени ожидания», оно будет делать это, и макет вернет ответ только после того, как он закончит ожидание. Если это «в тайм-аут, проверьте, есть ли ответ», он сделает это, и макет вернет ответ, только если он уже закончил ожидание.

MyStackRunnethOver 25.06.2019 00:58

Другие вопросы по теме