Макет пустого метода - PullRequest
       84

Макет пустого метода

0 голосов
/ 24 октября 2019

// Исходный метод:

@Autowired
    private ConversionServiceValidator validator; 

    public CRSConversionResult convertCRS(ConvertCrsVo convertCrsVo) throws Exception {

if (validator.isSameSourceAndTarget(convertCrsVo))
            throw new ValidationException(Constants.BADREQUEST);

        if (convertCrsVo.getPreferredTransforms() != null) {
            List<TransformVo> preferredTransformList = new ArrayList<>();
            for (TransformVo transformVo : convertCrsVo.getPreferredTransforms()) {
                preferredTransformList.add(getPerfByCode(transformVo));
            }
            convertCrsVo.setPreferredTransforms(preferredTransformList);
        }
        convertCrsVo.setSourceCRS(getCrsVoByCode(convertCrsVo.getSourceCRS()));
        convertCrsVo.setTargetCRS(getCrsVoByCode(convertCrsVo.getTargetCRS()));
        convertCrsVo = validator.replaceCoordinates(convertCrsVo);
        logger.info("ShellGeodeticService::convertCRS::Request to GeoCalService convertpoints::" + mapper.writeValueAsString(convertCrsVo));
        ConvertPointsResponse response = geoCalService.convertCRS(convertCrsVo);
        CRSConversionResult result = new CRSConversionResult();
        result.setCriteriaMessage(response.getCriteriaMessage());
        result.setResultPoints(response.getResultPoints());
        result.setTransformName(response.getTransformName());
        result.setTransformDescription(response.getTransformDescription());
        // added schema as per pbi 195298
        List<ConvertedTransformsResult> transformsResults = new ArrayList<>();
        if (response.getTransforms() != null || !response.getTransforms().isEmpty())
            response.getTransforms().stream().forEach(
                    t -> transformsResults.add(new ConvertedTransformsResult().getConvertedTransformsResult(t)));
        result.setTransforms(transformsResults);
        String logmessage=generateLogMessage(result,convertCrsVo);
        logger.info(logmessage);
        validator.isResponseValid(result);
        return result;
}

// Контрольный пример для вышеуказанного метода

@Test
    public void testconvertCRSJob() throws Exception{
        ConvertCrsVo convertCrsVo = TestDataFactory.getConvertCrsVo();
        CRSConversionResult crsConversionResult = TestDataFactory.getCRSConversionResult();
        ConversionServiceValidator conversionServiceValidatorMock = mock(ConversionServiceValidator.class);
Mockito.when(geoCalService.convertCRS(Mockito.any()))
        .thenReturn(TestDataFactory.getConvertPointsResponse(convertCrsVo));
Mockito.when(validator.replaceCoordinates(convertCrsVo))
        .thenReturn(TestDataFactory.getConvertCrsVo());
Mockito.when(geoCalService.search(Mockito.any(SearchFilter.class)))
        .thenReturn(TestDataFactory.getSearchResultResponseForCRS());
Mockito.when(shellGeodeticService.convertCRS(convertCrsVo))
        .thenReturn(TestDataFactory.getCRSConversionResult());  
shellGeodeticService.convertCRSJob();

        }

Я получаю следующую ошибку:

org.mockito.exceptions.misusing.CannotStubVoidMethodWithReturnValue: ' isResponseValid ' является пустым методом , и его не может быть заглушенным с возвращаемым значением ! Пустоты обычно заглушаются с помощью Throwables: doThrow (исключение) .when (mock) .someVoidMethod ();


Если вы не уверены, почему вы получаете ошибку выше, читайте дальше. Из-за особенностей приведенного выше синтаксиса проблема может возникнуть из-за того, что: 1. Метод, который вы пытаетесь заглушить, перегружен . Убедитесь, что вы вызываете правильную перегруженную версию. 2. Где-то в вашем тесте вы используете окончательные методы . Извините, Mockito не проверяет / заглушает финальные методы. 3. Шпион заглушается с использованием синтаксиса when (spy.foo ()). Then (). Безопаснее шпионить шпионов - с помощью семейства методов doReturn | Throw (). Больше в javadocs для метода Mockito.spy (). 4. Методы пересмотра, объявленные в закрытых родительских классах, не поддерживаются.

at com.shell.geodetic.GeodeticConvertionApiAppTests.testconvertCRSJob(GeodeticConvertionApiAppTests.java:1783)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

Может кто-нибудь помочь мне с тем, как заглушить метод void "isResponseValid"? Я попробовал около 100 комбинаций, которые я видел в SOF, и ничего не получалось. Заранее спасибо за помощь.

* Редактировать

Class ConversionServiceValidator {

    public void isResponseValid(CRSConversionResult response) throws InvalidDataException {

            if (response.getResultPoints().isEmpty() || response.getResultPoints() == null) {
                throw new ValidationException("Request body has incorrect format");
            } else {
                for (Point point : response.getResultPoints()) {
                    if (point.getX().trim().equals("0") || point.getY().trim().equals("0")) {
                        throw new InvalidDataException(400, "Bad Request", "WARNING: Not all points could be converted",
                                response);
                    }
                }
}

1 Ответ

0 голосов
/ 25 октября 2019

Это фиктивный @InjectMocks ShellGeodeticService shellGeodeticService;

shellGeodeticService не является фиктивным. @InjectMocks используется для тестируемого класса, в который вводится mocks.

Это означает, что вы не можете использовать

Mockito.when(shellGeodeticService.convertCRS(convertCrsVo)) 
       .thenReturn(TestDataFactory.getCRSConversionResult());

в своем тесте, поскольку только mocks (или spys) можно использовать в пределах Mockito.when.


На самом деле я пытаюсь запустить контрольный пример для shellGeodeticService.convertCRS (), и, поскольку он вызывает метод isResponseValid для внутреннего использования, я должен высмеивать это тоже верно?

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


Поскольку в вашем вопросе отсутствуют некоторые детали, я предполагаю, что полная версия вашего теста может быть похожа на эту:

@InjectMocks
ShellGeodeticService shellGeodeticService;

@Mock
ConversionServiceValidator validator;

@Mock
... geoCalService; // some unknown class

@Test
public void testconvertCRSJob() throws Exception{

    ConvertCrsVo convertCrsVo = TestDataFactory.getConvertCrsVo();

    // Note sure whether this is correct by your logic as there is no `replacement` happening.
    Mockito.when(validator.replaceCoordinates(convertCrsVo)).thenReturn(convertCrsVo);

    Mockito.when(geoCalService.convertCRS(Mockito.any())).thenReturn(TestDataFactory.getConvertPointsResponse(convertCrsVo));

    CRSConversionResult result = shellGeodeticService.convertCRS();

    // do some assertions on the result
}

Поскольку validator является макетом:

  • validator.isSameSourceAndTarget(convertCrsVo) возвращает false по умолчанию
  • validator.isResponseValid( ... ) по умолчанию ничего не делает

Поскольку вы не добавили методы getCrsVoByCode, getPerfByCode и generateLogMessage, обратите внимание, что если есть какие-либо дальнейшие взаимодействия с макетированными объектами, вам необходимо добавить их. (например, вызов geoCalService.search не виден в вашем тестовом коде, поэтому я удалил определение поведения из теста, показанного выше)

...