No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

No se trata de lo que quieres comprar, sino de quién quieres ser. Aprovecha el precio especial.

Antes: $249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

14 Días
14 Hrs
41 Min
44 Seg
Curso Básico de Testing en Java

Curso Básico de Testing en Java

Ferran Maylinch Carrasco

Ferran Maylinch Carrasco

Ejemplos de TDD: calcular el año bisiesto

13/24
Recursos

Descripción:
Los años bisiestos son años con 366 días en vez de 365 y suceden cada 4 años.

Para determinar si un año es bisiesto o no, debemos seguir las siguientes reglas:

  • Todos los años divisibles por 400 son bisiestos (1600, 2000, 2400)
  • Todos los años divisibles por 100 pero NO por 400 NO son bisiestos (1700, 1800, 1900)
  • Todos los años divisibles por 4 son bisiestos (1996, 2004, 2012)
  • Todos los años que NO son divisibles por 4 NO son bisiestos (2017, 2018, 2019)

Algunas clases de pruebas terminan con la palabra Should en lugar de Test porque podemos entenderlas como frases cuando se leen en conjunto con los nombres de los métodos.

Por ejemplo, la clase DateUtilLeapYearShould con su método return_true_when_year_is_divisible_by_400 pueden leerse como “Date utils leap year should return true when year is divisible by 400” o “Los utils para calcular el año bisiesto deben devuelven true cuando el año es divisible por 400”.

Aportes 39

Preguntas 3

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Dejo aqui las notas:

All years divisible by 400 ARE Leap years (1600, 2000, 2400)
All years divisible by 100 but not by 400 are NOT leap years (1700, 1880, 1900),
All years divisible by 4 but not by 100 ARE 1eap years (1996, 2004, 2008),
All years not divisible by 4 are NOT Leap years (2017, 2018, 2019)

Tener en cuenta que al dia de hoy la funccion assertThat esta marcado como deprecated en junit4

Me surgió una duda al ver este nuevo AssertThat. Ya que sentía que podría hacer lo mismo con un assertTrue o assertFalse. Busqué en internet, y encontré que el MOTIVO por el que se usa assertThat sobre estos otros es por: FACILIDAD DE LECTURA (Redability). Siento que lo explican MUY bien en esta página, asi que aquí os la dejo 😄. Espero os sirva

REFACTORING:

public static boolean isLeapYear(int year) {
        return (year % 4 == 0 && year % 100 != 0) || (year % 400) == 0;
    }

En TDD NUNCA se pasan los test a verde "por casualidad". Lo que pasa es que el profesor no ha seguido correctamente el proceso del TDD. 1. Escribimos los Test. 2. Desarrollamos el codigo. 3. Refactorizamo si es necesario .

para los que usan la versión 5 de junit
para usar el assertThat y el is

<dependency>
     <groupId>org.hamcrest</groupId>
     <artifactId>hamcrest-all</artifactId>
     <version>1.3</version>
     <scope>test</scope>
</dependency>

Una observación para los que esten viendo este curso sobre la metodologia de TDD, literal en la anterior clase se explicó que los pasos son ROJO(falla), VERDE(pasa) y AZUL(refactor).
En ese orden, debió haberse escrito el Test antes que el código, probar que fallará y luego si escribir el código que hiciera que pasará el test.
Pero acá no se siguió ese orden, y comenzamos con VERDE, para luego pasar a ROJO.

Si se hace como dicta TDD, sería algo asi:

  1. Escribir el test
  2. Error (ROJO), la clase no existe (DateUtil)
  3. Se crea la clase, se corre el Test
  4. Error (ROJO), la clase no tiene el metodo (isLeapYear)
  5. Se crea el metodo para que retorne falso siempre.
  6. Se corre el Test, error (ROJO), se espera true, se obtiene falso
  7. Se modifica el codigo para los casos multiplos de 400.
  8. Se corre el Test, pasa (VERDE).
  9. Se crea el nuevo Test, se corre, no pasa (ROJO)
  10. Se modifica el codigo, etc

Parece tedioso, pero asi es el flujo y en aras de la pedagogia hubiera sido bueno hacerlo asi.

por favor evitar usa los importes con *, así sea en casos prácticos, es mala práctica y si lo haces aprendiendo también lo haces en el trabajo saludos

Para quien esté viendo el video en 2022 o posterior y utiliza junit5

        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest</artifactId>
            <version>2.2</version>
            <scope>test</scope>
        </dependency>

Imports

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

Me gusta la idea del TDD, tienes tú, o quizás otro compañero alguna guía para implementarla en aplicaciones más del mundo real?
No sé bien como podría implementar TDD al hacer un microservicio, o al hacer una API,
Hay alguna guía para hacerlo? He intentado buscar por internet, pero no he dado con nada convincente.

DateUtil.java

package com.platzi.javatests.util;

public class DateUtil {

  public static boolean isLeapYear(int year) {
    return (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
  }
}

DateUtilLeapYearShould.java

package com.platzi.javatests.util;

import org.junit.Test;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

public class DateUtilLeapYearShould {
  /**
   * All years divisible by 400 ARE leap years (1600, 2000, 2400).
   * All years divisible by 100 but not by 400 are NOT leap years (1700, 1800, 1900).
   * All years divisible by 4 but not by 100 ARE leap years (1996, 2004, 2008).
   * All years are not divisible by 4 are NOT leap years (2017, 2018, 2019).
   */

  @Test
  public void returnTrue_whenYearIsDivisibleBy400() {
    assertThat(DateUtil.isLeapYear(1600), is(true));
    assertThat(DateUtil.isLeapYear(2000), is(true));
    assertThat(DateUtil.isLeapYear(2400), is(true));
  }

  @Test
  public void returnFalse_whenYearIsDivisibleBy100ButNotBy400() {
    assertThat(DateUtil.isLeapYear(1700), is(false));
    assertThat(DateUtil.isLeapYear(1800), is(false));
    assertThat(DateUtil.isLeapYear(1900), is(false));
  }

  @Test
  public void returnTrue_whenYearIsDivisibleBy4ButNotBy100() {
    assertThat(DateUtil.isLeapYear(1996), is(true));
    assertThat(DateUtil.isLeapYear(2004), is(true));
    assertThat(DateUtil.isLeapYear(2008), is(true));
  }

  @Test
  public void returnFalse_whenYearIsNotDivisibleBy4() {
    assertThat(DateUtil.isLeapYear(2017), is(false));
    assertThat(DateUtil.isLeapYear(2018), is(false));
    assertThat(DateUtil.isLeapYear(2019), is(false));
  }
}
public static boolean isLeapYear(int year){
        return (year % 400 == 0 || year % 100 == 0 || year % 4 == 0);
    }

El código lo vi cómo un poco más entendible de está manera:

public static boolean isLeapYear(int year){
        boolean divisibleBy4ByNotBy100 = (year % 4 == 0 && year % 100 != 0);
        boolean isJustDivisibleBy400 = (year % 400 == 0);
        boolean isDivisibleBy100ByNotBy400 = !(year % 100 == 0 && year % 400 != 0);
        return (isJustDivisibleBy400 || divisibleBy4ByNotBy100) && isDivisibleBy100ByNotBy400;
    }```

Sorprendente el Ide, ayuda mucho a detectar, implementar y refactorizar.

Buena clase gracias 😃

```js public class DateUtils { public static boolean isLeapYear(int year) { // Utilizando la clase Year de Java 8 para verificar si un año es bisiesto return Year.of(year).isLeap(); } } ```

Gran rapaso de la clase! Muchas gracias profesor!

public static boolean isLeapYear (int year){
        return (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
    }

return ( year % 400 == 0) ? true : ((year % 100 == 0) ? true : (year % 4 == 0)) ;

Tengo una duda no se supone que primero tenia que hacer fallar el test ya que es el paso numero

Aquí una versión optimizada de la función isLeapYear:

public static boolean isLeapYear(int year){
    return year % 4 == 0 && ( year % 100 != 0 || year % 400 == 0 );
}

En resumen, se acepta que un año es bisiesto si ocurren 2 cosas al mismo tiempo:

  1. El año es múltiplo de 4.
  2. El año no es múltiplo de 100 (esta segunda se descarta si es múltiplo de 400).

Otra posible solución:

public static boolean esBisiesto(int year) {
        return !(year % 100 == 0 && year % 400 != 0) ;
    }

Mi aporte de código en one line 😃

public static boolean isLeapYear(int year){
        return (year%400 == 0 || (year%4 == 0 && year%100 != 0))? true : false;
    }

Refactor 0.0

package Utils;

public class DateUtil {
    public static boolean isLeapYear(int year) {
        boolean isMultiple4 = year % 4 == 0 && year % 100 != 0;
        boolean isDivisibleFor400 = year % 400 == 0;

        return isMultiple4 || isDivisibleFor400;
    }

}

Test creados

<package com.prueba.test.utilidad;

import org.junit.Before;
import org.junit.Test;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

public class DateUtilsTest {

    private DateUtils dateUtils;

    @Before
    public void setUp() {
        dateUtils = new DateUtils();
    }


    @Test
    public void ifYearIsDivisibleBy400_IsLeap() {
        assertThat(dateUtils.isLeapYear(2000), is(true));
    }

    @Test
    public void ifYearIsDivisibleBy4ButItIsNotDivisibleBy400_IsNotLeap() {
        assertThat(dateUtils.isLeapYear(2019), is(false));
    }

    @Test
    public void ifYearIsDivisibleBy4ButItIsNotDivisibleBy100_IsLeap() {
        assertThat(dateUtils.isLeapYear(1996), is(true));
    }

    @Test
    public void ifYearIsNotDivisibleBy4_IsNotLeap() {
        assertThat(dateUtils.isLeapYear(2017), is(false));
    }
}>

DateUtil

    public static  boolean isLeadYear(int year){
        if ((year % 400 == 0) || ((year % 100 != 0)&&(year % 4 == 0))){
            return true;
        }
        return  false;
    }

public class DateUtilTest {

    @Test
    public void year_is_Leap() {
        boolean result = DateUtil.isLeadYear(1600);
        assertTrue(result);
         result = DateUtil.isLeadYear(2000);
        assertTrue(result);
         result = DateUtil.isLeadYear(1996);
        assertTrue(result);
         result = DateUtil.isLeadYear(2008);
        assertTrue(result);
    }
    @Test
    public void year_is_not_Leap() {
        boolean result = DateUtil.isLeadYear(1700);
        assertFalse(result);
        result = DateUtil.isLeadYear(2017);
        assertFalse(result);
        result = DateUtil.isLeadYear(2019);
        assertFalse(result);
        result = DateUtil.isLeadYear(2018);
        assertFalse(result);
    }
}

Muy buena clase, donde se pone en practica el TDD, y se explica como se debe de hacer

dateUtils

Muy buena clase y explicacion. Hay muchas personas que ofrecen codigos diferentes y la verdad es genial, cada quien tiene su tipo o forma de programar. Por lo menos yo ese tipo de simplicaciones como la que hizo en el if no me gustan, prefiero ver todo. Puede que en un codigo grande afecte, pero a futuro por lo menos para mi es mas facil entenderlo.

Por que los años 1700,1800 y 1900 no son bisiestos? el metodo se deberia simplemente con que el año sea divisible entre 4:

return year % 4 == 0;

Es aconsejable realizar muchas simplificaciones o es mejor que el código sea claro aunque implique ser un poco mas largo pero entendible

package com.platzi.JavaTEST.StringEmpty;

public class DateUtil {

	public static boolean isLeapYear(int year) {

		//forma 1
		return forma1(year);
		//return forma2(year);
		
	}
	
	public static boolean forma1(int year) {
		if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
			return true;
		} else {
			return false;
		}
	}
	
	public static boolean forma2(int year) {
		return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
	}
}

package com.platzi.JavaTEST.StringEmpty;

import static org.hamcrest.CoreMatchers.is;
import org.junit.Test;
import static org.junit.Assert.assertThat;

public class DateUtilShould {

	/**
	 * All years divisible by 400 ARE leap years (1600, 2000, 2400). All years
	 * divisible by 100 but not by 400 are NOT leap years (1700, 1800, 1900). All
	 * years divisible by 4 but not by 100 ARE leap years (1996, 2004, 2008). All
	 * years are not divisible by 4 are NOT leap years (2017, 2018, 2019).
	 */

	@Test
	public void return_true_when_year_is_divisible_by_400() {
		assertThat(DateUtil.isLeapYear(2000), is(true));
		assertThat(DateUtil.isLeapYear(1600), is(true));
		assertThat(DateUtil.isLeapYear(2400), is(true));
	}

	@Test
	public void return_false_when_year_is_divisible_by_100_but_not_by_400() {
		assertThat(DateUtil.isLeapYear(1700), is(false));
		assertThat(DateUtil.isLeapYear(1800), is(false));
		assertThat(DateUtil.isLeapYear(1900), is(false));
	}

	@Test
	public void return_true_when_years_are_divisible_by_4_but_not_by_100() {
		assertThat(DateUtil.isLeapYear(1996), is(true));
		assertThat(DateUtil.isLeapYear(2004), is(true));
		assertThat(DateUtil.isLeapYear(2008), is(true));
	}

	@Test
	public void return_false_when_years_arent_divisible_by_4() {
		assertThat(DateUtil.isLeapYear(2017), is(false));
		assertThat(DateUtil.isLeapYear(2018), is(false));
		assertThat(DateUtil.isLeapYear(2019), is(false));
	}
}

En programación funcional se me ocurrió esto ¿Tal vez, se podría hacer mejor?

public class DateUtil {

    public static boolean isLeadYear(int year) {
        Predicate<Integer> divisibleBy400 = x -> x % 400 == 0;
        Predicate<Integer> divisibleBy4AndNotBy100 = x -> x % 4 == 0 && x % 100 != 0;

        return divisibleBy400.or(divisibleBy4AndNotBy100).test(year);
    }
}

Se crean primero los tests de esta manera vamos escribiendo el código necesario para que los test fallen.
Una vez que fallan se ajusta el código para que tengan éxito y una vez teniendo éxito en todas los test, se optimiza el código.

En Kotlin.

 fun isLeapYear(year : Int) : Boolean{
        return when {
            year % 400 == 0 && year % 4 == 0  -> {
                true
            }
            else -> {
                false
            }
        }
    }

Excelente clase instructor Ferran, con el uso de este enfoque de programación podremos verificar que parte esté funcionando e iremos notando que partes podremos mejorar.

Gracias

Hola, a mi me quedó así

DateUtilLeapYear

public class DateUtilLeapYear {

    public boolean isLeapYear(int year) {
        return year % 100 != 0 || year % 400 == 0;
    }

}

DateUtilLeapYearShould

class DateUtilLeapYearShould {

    @Test
    public void return_true_when_year_is_divisible_by_400() {
        assertTrue(new DateUtilLeapYear().isLeapYear(1600));
        assertTrue(new DateUtilLeapYear().isLeapYear(2000));
        assertTrue(new DateUtilLeapYear().isLeapYear(2400));
    }

    @Test
    public void return_false_when_year_is_divisible_by_100_but_not_by_400() {
        assertFalse(new DateUtilLeapYear().isLeapYear(1700));
        assertFalse(new DateUtilLeapYear().isLeapYear(1800));
        assertFalse(new DateUtilLeapYear().isLeapYear(1900));
    }

    @Test
    public void return_true_when_year_is_divisible_by_4() {
        assertTrue(new DateUtilLeapYear().isLeapYear(1996));
        assertTrue(new DateUtilLeapYear().isLeapYear(2004));
        assertTrue(new DateUtilLeapYear().isLeapYear(2012));
    }

    @Test
    public void return_false_when_year_is_not_divisible_by_4() {
        assertTrue(new DateUtilLeapYear().isLeapYear(2017));
        assertTrue(new DateUtilLeapYear().isLeapYear(2018));
        assertTrue(new DateUtilLeapYear().isLeapYear(2019));
    }

}