DateFormat unittest falla en Jenkins, pero no a nivel local

Hamza Inca:

He hecho una unidad de prueba de un servicio, cuando yo haga el trabajo Jenkins, cada método de prueba pasan correctamente, excepto uno.
Pero este método de ensayo, funciona en mi máquina, tanto con Eclipse y utilizando el mvncomando.

    // TARGET_RUN_DATE_OF_YEAR = "2018-01-01"
    @Test
    public void dateToTimestamp() {
        Service service = getService();

        String df = "YYYY-MM-dd";
        String invalid = "INVALID";

        // Check success
        Timestamp timestamp = service.dateToTimestamp(TARGET_RUN_DATE_OF_YEAR, df);
        Assert.assertEquals(service.getTodayTimestamp(), timestamp); // <-- Fail here
        // Check failure
        Assert.assertNull(service.dateToTimestamp(TARGET_RUN_DATE_OF_YEAR, invalid));
        Assert.assertNull(service.dateToTimestamp(invalid, df));
    }

El servicio tiene métodos Mulitple:

  • getTodayTimestamp Danos hoy Marca de tiempo, se pone a prueba este método, que funciona en mi máquina y en Jenkins.
  • dateToTimestamp toma una fecha y una dateFormat como cadenas, y devuelve la fecha como una marca de tiempo, este método es el que no trabaja.

El dateToTimestampmétodo en el servicio:

    private Timestamp dateToTimestamp(String date, DateFormat df) throws ParseException {
        return new Timestamp(df.parse(date).getTime());
    }

    @Override
    public Timestamp dateToTimestamp(String date, String dateFormatString) {
        try {
            DateFormat df = new SimpleDateFormat(dateFormatString);
            return dateToTimestamp(date, df);
        } catch (Exception e) {
            log.warn("Exception during conversion of date to timestamp, exception : {}", e);
            return null;
        }
    }

Como ya he dicho anteriormente, el trabajo de prueba perfectamente en mi pc, pero no en Jenkins (añadiendo las @Ignoreanotaciones a este método, hace que el trabajo con éxito).
Al poner en marcha el trabajo, me sale este error:

pruebas fallidas: dateToTimestamp (com.test.service.ServiceImplTest): Se esperaba: <2018-01-01 00: 00: 00.0> <pero fue: 31/12/2017 00: 00: 00.0>

Lo que puedo asegurar, es que incluso en Jenkins, el dateToTimestampmétodo toma los parámetros TARGET_RUN_DATE_OF_YEAR, lo que es "2018-01-01"y la cadena dateFormart como "YYYY-MM-dd". Pero aún así devuelve 2017-12-31 00:00:00.0como marca de tiempo.

¿Algunas ideas?

VV Ole:

java.time

Estoy asumiendo que quería una Timestamppara usar con su base de datos SQL. No utilice Timestamppara ello en 2019. Esa clase está mal diseñado y largo obsoleta.

  • Si el tipo de datos en el lado de SQL es timestamp with time zone(que debería ser para una marca de tiempo), utilice OffsetDateTimeen Java.
  • Si en el lado de SQL que necesita un simple timestamp(sin zona horaria), el uso LocalDateTimede Java.

Código de ejemplo:

    String dateString = "2018-01-01";
    OffsetDateTime odt = LocalDate.parse(dateString)
            .atStartOfDay()
            .atOffset(ZoneOffset.UTC);

    System.out.println(odt);

La salida es:

2018-01-01T00: 00Z

Ahora se puede pasar su OffsetDateTimea JDBC usando algo como:

    yourPreparedStatement.setObject(4, odt);

Lo que salió mal en el código?

Creo que está experimentando la combinación de dos cuestiones:

  • El uso de mayúsculas YYYYen la cadena de patrón de formato no es correcto. Mayúscula Yes para basada semana del año y sólo es útil con un número de la semana. Con el viejo y problemático SimpleDateFormatque habría necesitado minúsculas ypara el año.
  • (Las JVM) en su máquina y el servidor Jenkins tienen diferentes lugares predeterminados.

Demostrar:

    String dateString = "2018-01-01";
    String dateFormatString = "YYYY-MM-dd"; // Incorrect format pattern string
    DateFormat df = new SimpleDateFormat(dateFormatString);
    System.out.println(df.parseObject(dateString));

Salida en mi equipo (configuración regional de Dinamarca, Europa / Copenhague zona horaria):

Mi 01 de enero de 2018 0:00:00 CET

Sin embargo si primero hago esto:

    Locale.setDefault(Locale.US);

- a continuación, la salida del fragmento anterior es diferente, a saber:

Dom Dic 31 de 2017 00:00:00 CET

Lo que sucede es que SimpleDateFormatse da por vencido en la determinación de una fecha exacta del año en función semana, mes y día del mes y en su lugar sólo le da la primera fecha del año en función semana. Es un comportamiento típico de SimpleDateFormatdarle un resultado que no puede ser correcto y, sin embargo, pretender que todo está bien. En algunos lugares la semana comienza el lunes, y se obtiene Lun Ene 01, el cual casualmente está de acuerdo con su cadena. En otros lugares, como los EE.UU., la semana comienza el domingo, así que en vez se obtiene Dom Dic 31 del año anterior.

Enlace

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=336419&siteId=1
Recomendado
Clasificación