Как избежать вызова каскада внутренних структур методов при выполнении тестового примера Junit и макета для конкретного метода - PullRequest
1 голос
/ 05 апреля 2019

Я создаю тестовый пример, используя Junit для публичного метода. Этот метод вызывает частный метод в том же классе, и этот частный метод в конечном счете вызывает последовательность других методов в отдельных классах, согласно бизнес-логике. Все методы возвращают ConcurrentHashMap , и я просто хочу проверить assertNotNull на возвращаемое значение.
Как мне избежать каскада вызовов методов?

Если я буду издеваться над всеми методами потока, то мой тестовый пример станет огромным. Как я могу избежать этих вызовов и просто выполнить тестирование черного ящика только для моего метода, то есть передача параметров и ожидаемый возврат .

Мой метод:

public ConcurrentHashMap<String, Object> checkValidation(Validation validationData,
            ConcurrentHashMap<String, Object> srcHMData, Statement statement) {
        Column[] columnArray = validationData.getColumnArray();
        ConcurrentHashMap<String, Object> processedData = new ConcurrentHashMap<String, Object>();
        ConcurrentHashMap<String, Object> validationData = null;

        if (columnArray != null && columnArray.length > 0) {
            for (int i = 0; i < columnArray.length; i++) {
                validationData = new ConcurrentHashMap<String, Object>();
                Column colVal = columnArray[i];
                String validationName = colVal.getName();
                validationData = processValidation(validationName, srcHMData, statement);

                processedData.putAll(validationData);
            }
        }
    return processedData;

}

Закрытый метод, который вызывается из этого класса:

private ConcurrentHashMap<String, Object> processValidation(String validationName,
            ConcurrentHashMap<String, Object> srcHMData, Statement statement) {

        ConcurrentHashMap<String, Object> validationData = new ConcurrentHashMap<String, Object>();
        try {
            TransformationProcess transferObj = new TransformationProcess();
            validationData = transferObj.checkTransformation(srcHMData, statement);
        } catch (Exception e1) {
            e1.printStackTrace();
        }

    return validationData;

}

Мой метод тестирования, который я пробовал как:

TransformationProcess transMock = mock(TransformationProcess.class);
when(transMock.checkTransformationRule(Mockito.any(), eq(dummyDataMap), eq(mockStatement))).thenReturn(validationDataMap);

Я хочу избежать вызова внутренних методов из этой строки в приватном методе -

validationData = transferObj.checkTransformation(srcHMData, statement);

и просто хочу вернуть макет ConcurrentHashMap из этой строки, чтобы я мог проверить assertNotNull или какой-либо другой. Но хотя эта строка встречается, она вызывает весь бизнес-поток и в конечном итоге получает исключение NullPointer.

1 Ответ

0 голосов
/ 06 апреля 2019

Вы не можете использовать mockito для насмешки над вызовом new. Здесь у вас есть два варианта: во-первых, нужно перейти на powermock, который может сделать гораздо больше, чем mockito, но рекомендуется только для унаследованного кода, во-вторых, это реорганизовать ваш код, чтобы вы могли внедрить зависимость TransformationProcess в ваш Validator.

Вы можете напрямую ввести TransformationProcess в ваш метод:

public ConcurrentHashMap<String, Object> checkValidation(Validation validationData,
            ConcurrentHashMap<String, Object> srcHMData, Statement statement, TransformationProcess transformationProcess)

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

Или зависимость может быть введена через конструктор:

Validator(TransformationProcess transformationProcess)

И теперь вместо того, чтобы каждый раз создавать новый экземпляр, вы можете повторно использовать тот же экземпляр, который уже есть в вашем объекте. Если вам каждый раз нужен новый экземпляр TransformationProcess, вы можете вставить в конструктор оболочку TransformationProcess, которая предоставит новый экземпляр:

Validator(TransformationProcessProvider transformationProcessProvider)
...
TransformationProcess transformationProcess = transformationProcessProvider.getTransformationProcess();

И теперь вы можете создать макет TransformationProcessProvider и передать его тестируемому объекту:

TransformationProcessProvider providerMock = mock(TransformationProcessProvider.class);
TransformationProcess transMock = mock(TransformationProcess.class);

when(providerMock.getTransformationProcess()).thenReturn(transMock);
when(transMock.checkTransformationRule(Mockito.any(), eq(dummyDataMap), eq(mockStatement))).thenReturn(validationDataMap);

Validator validatorUnderTest = new Validator(providerMock);
...