LocalValidatorFactoryBean не проверяется при тестировании - PullRequest
0 голосов
/ 18 февраля 2020

Я пишу серию тестов для приложения Camel (источник которого находится в / src / main / java) в / src / test / java в классе CamelContextXmlTest. java.

Поскольку я не хотел переопределять в Java DSL уже определенные маршруты в верблюжьем контексте. xml Я просто добавил "обходные пути" или перехватил существующие маршруты, чтобы добавить фиктивные конечные точки:

public class CamelContextXmlTest extends CamelSpringTestSupport {


    @Override
    public boolean isUseAdviceWith() {
        // tell we are using advice with, which allows us to advice the route
        // before Camel is being started, and thus can replace activemq with something else.
        return true;
    }

    @Before
    public void reconfigurarRutaExistente() throws Exception {
        //Create routes from the output endpoints to our mock endpoints so we can assert expectations
                context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() {
                    @Override
                    public void configure() throws Exception {
                         interceptSendToEndpoint("{{rest.url.path}}")
                         .skipSendToOriginalEndpoint()
                         .choice()
                         .when(header("X-Test-Disponible").contains("true") )
                            .log("Simulating change in body by connection to WS")
                            .transform(constant("{ \"vCodRet\": \"550\",  \"vCodRetRev\": \"000\"}"))
                            .to(resultWebApi)
                         .otherwise()
                            .to(resultWSNoavailable);

                         weaveById("_throwException1").before().to(resultJsonInvalid);
                         weaveById("_responseProcessor").after().to(resultProcessorResponse);

                    }
                });
                context.start();

    }

   @Test
   public void someTest(){
        ...
   }

}

С другой стороны, в моем верблюжьем контексте, в одном из моих маршрутов у меня есть это: <process id="_processValidateData" ref="validateData"/>, который ссылается на этот бин в контексте приложения. xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />

    <bean class="com.bancoppel.coppel.bya.processors.ValidateData" id="validateData" />
    <bean class="com.bancoppel.coppel.bya.processors.GenerateResponseError" id="response-processor" />

     <!-- Some other beans -->

</beans>

Класс ValidateData определяется следующим образом:

public class ValidateData implements Processor{

    protected static final Logger LOGGER = LoggerFactory.getLogger(ValidateData.class);


    @Autowired
    private ValidatorService validatorService;// = new ValidatorService();
    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void process(Exchange exchange){

        LOGGER.info("Reading body request...");
        String jsonObject = exchange.getIn().getBody(String.class);
        LOGGER.info(jsonObject);
        if (validatorService == null) {validatorService = new ValidatorService(); }
        try {
            if(validatorService.isValidJson(jsonObject)){

                LOGGER.debug(jsonObject);

                Object  request = this.objectMapper.readValue(jsonObject, ReqTransCtasPropias.class);

                LOGGER.info("Validating request");

                **Errors errors = validatorService.isValidSyntax(request);** //This where is not working

                if (errors == null) {
                //Extract header node without deserializing.
                com.fasterxml.jackson.databind.JsonNode parent = this.objectMapper.readTree(jsonObject);
                String cabceraTexto = this.objectMapper.writeValueAsString(parent.get("cabecera"));


                //Validate header
                Cabecera cabeceraRequest = this.objectMapper.readValue(cabceraTexto, Cabecera.class);
                Errors errorCabecera = validatorService.isValidSyntax(cabeceraRequest);
                errors = errorCabecera;

                }

                if(errors == null){
                    exchange.getIn().setBody( this.objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(request));
                    exchange.getIn().setHeader("validated", "pass");
                }else{
                    LOGGER.error("Detected errors at validating json syntax of body request");
                    exchange.getIn().setHeader("CamelHttpResponseCode",Message.HTTP_ERROR_400);
                    exchange.getIn().setHeader("TYPE_ERROR",Message.HTTP_ERROR_400);
                    throw new Exception("Syntax error: Errors[" + errors.getErrorCount() + "] Desc: " + errors.getFieldError());
                }
            }else{
                exchange.getIn().setHeader("CamelHttpResponseCode",Message.HTTP_ERROR_400);
                exchange.getIn().setHeader("TYPE_ERROR",Message.HTTP_ERROR_400);
                throw new Exception("Json malformed.");
            }

        } catch(Exception m) {
            exchange.getIn().setHeader("CamelHttpResponseCode",Message.HTTP_ERROR_400);
            exchange.getIn().setHeader("TYPE_ERROR",Message.HTTP_ERROR_400);
            LOGGER.error("ErrorResponse reading parameters",m);
        }

    }
}

Когда я начал делать некоторые тесты и запускал их с тестом Maven, у меня были некоторые исключения NullPointerException, которые не позволяли мне их завершить. Затем я выясняю, почему: Вероятно, это связано с аннотациями @Autowired, которые, честно говоря, я не знаю, как они работают, но, по-видимому, вводит или инициализирует некоторые переменные во время выполнения или отладки (как приложение Java), но не в Maven test. В классе ValidateDate у меня есть такой:

@Autowired
    private ValidatorService validatorService;

Чтобы обойти эту проблему, я просто добавил if (validatorService == null) {validatorService = new ValidatorService(); }, и это работало так же во время теста Maven и обычного Java запуска приложения.

Это работало для моих тестов, кроме одного, потому что эта служба валидатора не работает должным образом в моем методе isValidSyntax при тестировании maven, но она хорошо работает при нормальном выполнении. Вот определение этого класса:

public class ValidatorService  {
    protected static final Logger LOGGER = LoggerFactory.getLogger(ValidatorService.class);
    private final static ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    //private Validator validator; 
    private org.springframework.validation.beanvalidation.LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); //Here workaround again with a new() because this was getting NullPointException too.

        public Errors isValidSyntax(Object request) {
            BeanPropertyBindingResult requestResult = new BeanPropertyBindingResult(request, "ReqTransCtasPropias");

            LOGGER.info(validator.toString());
            LOGGER.info(request.toString());
            LOGGER.info(requestResult.toString());
            //LOGGER.info( errors == null ? "Null" : "No"  );

            //validator.getValidator();
            validator.validate(request, requestResult); //Workarounds allow me to get here, but this doesn't validate properly, it throws me no errors.
            LOGGER.info(requestResult.toString());
            if (!requestResult.hasErrors()) {
                LOGGER.debug("[usuarioRequestResult]: [OK]");
                LOGGER.debug("[MandatoryFields]: [OK]");
                return null;
            } else {
                LOGGER.error("[applicationRequestResult]: Total Errors [" + requestResult.getErrorCount() + "]" + " Descripcion [" + requestResult.getFieldError() + "]");
                return requestResult;
            }

        }

    public  boolean isValidJson(final String json) throws IOException {
        ... Omitted because this post is getting to long ...
    }

    }

Как я уже сказал, я вручную инициализирую переменные в коде как обходной путь, но это приводит к тому, что validator.validate(request, requestResult) не работает должным образом. Он должен взять объект и сравнить его с классом, который содержит аннотации проверки JavaScript, такие как @NotNull, @NotBlank, @Pattern и др. c. При нормальном выполнении приложения (или отладке), по-видимому, изменяется некоторое свойство в requestResult (экземпляр BeanPropertyBindingResult), когда присутствуют ошибки, поэтому hasErrors () также работает. Но не в тесте Maven, он просто не сообщает об ошибке, когда аннотация не встречается.

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

Что я могу сделать, чтобы этот тест Maven работал правильно? Есть ли что-то связанное с тем, что Spring Boot обычно загружает что-то во время выполнения, чего у меня нет в тестовом окружении Maven?

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

...