Проверка частично упорядоченных вызовов методов в JMockit - PullRequest
1 голос
/ 09 апреля 2011

Я пытаюсь написать модульный тест (используя JMockit), который проверяет, что методы вызываются в соответствии с частичным порядком.Конкретный вариант использования гарантирует, что определенные операции вызываются внутри транзакции, но в более общем случае я хочу проверить что-то вроде этого:

  • Метод beginTransaction вызывается.
  • Методы *Вызываются от 1007 * до operationN в любом порядке.
  • Вызывается метод endTransaction.
  • Метод someOtherOperation вызывается за некоторое время до, во время или после транзакции.

API ожиданий и проверок, кажется, не в состоянии справиться с этим требованием.

Если у меня есть @Mocked BusinessObject bo, я могу проверить, что правильные методы вызываются (в любом порядке) с этим:

new Verifications() {{
    bo.beginTransaction();
    bo.endTransaction();
    bo.operation1();
    bo.operation2();
    bo.someOtherOperation();
}};

при желании сделать его FullVerifications для проверки отсутствия других побочных эффектов.

Чтобы проверить ограничения порядка, я могу сделать что-то вроде этого:

new VerificationsInOrder() {{
    bo.beginTransaction();
    unverifiedInvocations();
    bo.endTransaction();
}};

, но это не относится к случаю someOtherOperation.Я не могу заменить unverifiedInvocations на bo.operation1(); bo.operation2(), потому что это помещает в вызовы порядок total .Корректная реализация бизнес-метода может вызвать bo.operation2(); bo.operation1().

Если я сделаю это:

new VerificationsInOrder() {{
    unverifiedInvocations();
    bo.beginTransaction();
    unverifiedInvocations();
    bo.endTransaction();
    unverifiedInvocations();
}};

, то при вызове someOtherOperation я получаю ошибку «Нет проверенных вызовов осталось»до сделки.Попытка bo.someOtherOperation(); minTimes = 0 также не работает.

Итак: есть ли чистый способ указать требования к частичному упорядочению для вызовов методов с использованием API ожиданий / проверок в JMockIt?Или я должен использовать MockClass и вручную отслеживать вызовы, a la :

@MockClass(realClass = BusinessObject.class)
public class MockBO {
    private boolean op1Called = false;
    private boolean op2Called = false;
    private boolean beginCalled = false;

    @Mock(invocations = 1)
    public void operation1() {
        op1Called = true;
    }

    @Mock(invocations = 1)
    public void operation2() {
        op2Called = true;
    }

    @Mock(invocations = 1)
    public void someOtherOperation() {}

    @Mock(invocations = 1)
    public void beginTransaction() {
        assertFalse(op1Called);
        assertFalse(op2Called);
        beginCalled = true;
    }

    @Mock(invocations = 1)
    public void endTransaction() {
        assertTrue(beginCalled);
        assertTrue(op1Called);
        assertTrue(op2Called);
    }
}

1 Ответ

0 голосов
/ 16 января 2014

если вам действительно нужен такой тест, то: не используйте библиотеку макетов, но создайте свой собственный макет с состоянием внутри, который может просто проверить правильный порядок методов.но тестирование порядка вызовов обычно является плохим признаком.Мой совет: не проверяйте это, рефакторинг.Вы должны проверить свою логику и результаты, а не последовательность вызовов.проверьте правильность побочных эффектов (содержание базы данных, взаимодействие служб и т. д.).если вы тестируете последовательность, то ваш тест в основном является точной копией вашего производственного кода.Так в чем же ценность такого теста?и такой тест также очень хрупкий (как любое дублирование).

возможно, вы должны сделать так, чтобы ваш код выглядел так:

beginTransaction()
doTransactionalStuff()
endTransaction()
doNonTransactionalStuff()
...