Невозможно выполнить модульный тест Java код использует отражение с Mockito или PowerMockito - PullRequest
0 голосов
/ 15 января 2020

Я пытаюсь написать модульный тест, чтобы протестировать этот кусок кода, но я потерпел неудачу в пределах Mockito / Powermockito с собственным классом java .lang.Class, как объяснено здесь .

Как я могу проверить это:

Method[] serverStatusMethods = serverStatus.getClass().getMethods();
    for (Method serverStatusMethod : serverStatusMethods) {
        if (serverStatusMethod.getName().equalsIgnoreCase("get" + field)) {
            serverStatusMethod.setAccessible(true);
            try {
                Number value = (Number) serverStatusMethod.invoke(serverStatus);
                response = new DataResponse(field + " value", value);
            } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
                Logger.getLogger(StatusServlet.class.getName()).log(Level.SEVERE, null, ex);
                response = new ErrorResponse(HttpStatus.Code.INTERNAL_SERVER_ERROR, ex);
            }
            break;
        }
    }

, чтобы преднамеренно выдать это исключение в тестовом примере:

catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
            Logger.getLogger(StatusServlet.class.getName()).log(Level.SEVERE, null, ex);
            response = new ErrorResponse(HttpStatus.Code.INTERNAL_SERVER_ERROR, ex);
}

1 Ответ

2 голосов
/ 15 января 2020

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

public Number resolveServerStatus(Object serverStatus)
    throws IllegalAccessException, IllegalArgumentException,
        InvocationTargetException {

    Method[] serverStatusMethods = serverStatus.getClass().getMethods();
    for (Method serverStatusMethod : serverStatusMethods) {
        if (serverStatusMethod.getName().equalsIgnoreCase("get" + field)) {
            serverStatusMethod.setAccessible(true);
            return (Number) serverStatusMethod.invoke(serverStatus);
        }
    }
}

Теперь смейтесь над методом resolveServerStatus.

Это то, что вы должны были сделать в первую очередь, если бы следовали принцип единоличной ответственности . Ваш метод имел две обязанности: разрешение номера статуса и преобразование его в DataResponse объект. Многочисленные обязанности затруднили тестирование метода.

...