No tienes acceso a esta clase

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

Curso Básico de Testing en Java

Curso Básico de Testing en Java

Ferran Maylinch Carrasco

Ferran Maylinch Carrasco

Creación de la base de datos y tests de integración con bases de datos

19/24
Recursos

Para realizar un test de integración a la base de datos utilizaremos Spring y H2, asegúrate de copiar el siguiente código a tus dependencias:

<dependency>
  <groupId>org.springframeworkgroupId>
  <artifactId>spring-jdbcartifactId>
  <version>5.1.3.RELEASEversion>
dependency>
<dependency>
  <groupId>org.h2databasegroupId>
  <artifactId>h2artifactId>
  <version>1.4.197 version>
dependency>

Java necesita el método equals para poder comparar objetos correctamente, por ello debemos añadirlos a nuestra clase.

Aportes 27

Preguntas 8

Ordenar por:

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

Ola las dependencias que indica el profe me estaban dando problemas, así que usé:

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.1.3.RELEASE</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.192</version>
        </dependency>

Dejo las sentencias del archivo test-data.sql por si alguien las quiere copiar

CREATE TABLE IF NOT EXISTS movies(
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    minutes INT NOT NULL,
    genre VARCHAR(50) NOT NULL
);

INSERT INTO movies (name, minutes, genre) VALUES
    ('Dark Knight', 152, 'ACTION'),
    ('Memento', 113, 'THRILLER'),
    ('Matrix', 136, 'ACTION')

Estuve probando una mejora para que no inicie una conexión a la base de datos cada vez que se ejecuta un test. Ences declaré un atributo estático de dataSource.

El script SQL se va a ejecutar antes de todos los test para reiniciar los datos-

public class PeliculaRepositoryIntegrationTest {

    private static DataSource dataSource = new DriverManagerDataSource("jdbc:h2:mem:test;MODE=MYSQL", "sa", "sa");
    private static JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
    private PeliculaRepositoryJDBC peliculaRepository;

    @Before
    public void setup() throws ScriptException, SQLException {
        ScriptUtils.executeSqlScript(dataSource.getConnection(), new ClassPathResource("sql\\test-data.sql"));
        peliculaRepository = new PeliculaRepositoryJDBC(jdbcTemplate);
    }

    @Test
    public void deberia_retornar_todas_las_peliculas()  {
        Collection<Pelicula> pelis =  peliculaRepository.findAll();
        assertThat(pelis, is(Arrays.asList(
            new Pelicula(1, "Dark Knight", 152, Genero.ACCION) ,
            new Pelicula(2, "Memento", 113, Genero.DRAMA) ,
            new Pelicula(3, "Matrix", 136, Genero.ACCION)
        )));
    }
}

Visto que es un script sql de test, tambien lo hice de esta manera y funciono:

DROP TABLE IF EXISTS movies;

CREATE TABLE IF NOT EXISTS movies (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(50) NOT NULL,
  minutes INT NOT NULL,
  genre VARCHAR(50) NOT NULL

	.
	.
	.
);

Pueden por favor explicar como crear el package sql-script y el
archivo sql-data.sql Favor

Las dependencias indicadas en los recursos de la clase están mal escritas. Comparto como quedarían funcionando bien, para ahorrarles tiempo:

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.1.3.RELEASE</version>
</dependency>

<dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.197</version>
</dependency>

Comparto dependencias actualizadas

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-all</artifactId>
            <version>1.3</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>4.4.0</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.19.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>2.1.210</version>
        </dependency>

    </dependencies>

Corregido:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.1.3.RELEASE</version>
    </dependency>
         <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <version>1.4.197</version>
        <scope>test</scope>
    </dependency>

que bien esas pruebas de integracion usando base de datos en memoria con h2 y spring-jdbc como template.

Buen día, tengo una pregunta: Como consiguió la ruta de la base de datos que pega en el minuto 7:54?

Excelente. Aunque para que quede el código más limpio se puede hacer de la siguiente forma.

package com.platzi.javatests.movies.data;

import com.platzi.javatests.movies.model.Movie;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.datasource.init.ScriptUtils;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Collection;

import static com.platzi.javatests.movies.model.Genre.ACTION;
import static com.platzi.javatests.movies.model.Genre.THRILLER;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

@RunWith(MockitoJUnitRunner.class)
public class MovieRepositoryIntegrationTest {

  @InjectMocks
  MovieRepositoryJdbc movieRepository;

  @Mock
  JdbcTemplate jdbcTemplate;

  @Before
  public void setUp() throws SQLException {
    // Database in-memory.
    DataSource dataSource = new DriverManagerDataSource("jdbc:h2:mem:test;MODE=MYSQL", "sa", "sa");
    jdbcTemplate = new JdbcTemplate(dataSource);
    movieRepository = new MovieRepositoryJdbc(jdbcTemplate);

    // Insert test data into the in-memory database.
    ScriptUtils.executeSqlScript(dataSource.getConnection(), new ClassPathResource("sql-scripts/test-data.sql"));
  }

  @Test
  public void loadAllMovies() {
    Collection<Movie> movies = movieRepository.findAll();

    assertThat(movies, is(Arrays.asList(
      new Movie(1, "Dark Knight", 152, ACTION),
      new Movie(2, "Memento", 113, THRILLER),
      new Movie(3, "Matrix", 136, ACTION)
    )));
  }
}

Me daba continuamente error hasta que me percaté que en el método equals de la clase Movie no hay que incluir el id ya que en la comparativa no lo estaba evaluando. También es importante destacar que estoy evaluando las condiciones con assertEquals y no con assertThat, ya que éste último está deprecated en 2023.

Les dejo el método equals el hashCode de la clase Movie por si a alguien le sirve:

@Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Movie movie = (Movie) o;
        return minutes == movie.minutes &&
//Line to be deleted		
//Objects.equals(id,movie.name &&
                Objects.equals(name, movie.name) &&
                genre == movie.genre;
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, minutes, genre);
    }

Y esta sería la comparativa correspondiente que se realiza en el apartado de los tests:

	//List of expected movies to be obtained
        List <Movie> listOfExpectedMovies  = Arrays.asList(
                new Movie("Dark Knight", 152, Genre.ACTION),
                new Movie("Memento", 113, Genre.THRILLER),
                new Movie("Matrix", 136, Genre.ACTION)
        );

        /*
        System.out.println("Expected:");
        for (Movie movie : listOfExpectedMovies) {
            System.out.println(movie.getName()+"\t"+movie.getMinutes()+"\t"+ movie.getGenre());
        }*/

        //Collection of all movies obtained by the database
        Collection<Movie> allMovies = movieRepositoryJdbc.findAll();

        /*
        System.out.println("Obtained:");
        for (Movie movie : allMovies) {
            System.out.println(movie.getName()+"\t"+movie.getMinutes()+"\t"+ movie.getGenre());
        }*/

        assertEquals(listOfExpectedMovies, allMovies);

Espero que les sirva.

Por si alguno tiene problemas, seguí al profesor pero no me funcionó con el assertThat sino con assertEquals

    @Test
    public void load_all_movies() {

               Collection<Movie> moviesCollection = movieRepoJdbc.findall();
               Collection<Movie> list=Arrays.asList(
                new Movie(1, "Dark Knight", 152, Genre.ACTION) ,
                new Movie(2, "Memento", 113, Genre.THRILLER) ,
                new Movie(3, "Matrix", 136, Genre.ACTION)
        );
//        assertThat(moviesCollection, is(Arrays.asList(
//                new Movie(1, "Dark Knight", 152, Genre.ACTION) ,
//                new Movie(2, "Memento", 113, Genre.DRAMA) ,
//                new Movie(3, "Matrix", 136, Genre.ACTION)
//        )));
        assertEquals(moviesCollection,list);
    }

dependencias de mi pom.xml

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>3.8.0</version>
            <scope>test</scope>

        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.1.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.200</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

Estupenda clase instructor Ferran, todavía sigue impresionándome como quedan los métodos al cambiar a lambda.

Excelente clase… 👍

Gracias profe

En eclipse la opcion de generar los metodos equals y hashcode se encuentra aca:

Sufri demasiado ya que mi proyecto es intelij no es generado sino que cree manualmente todos los paquetes, me hacian falta todas las librerias de spring y apache, tambien tuve que crear la configuracion de h2
````txt <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>5.8.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>6.1.0</version> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>2.2.220</version> </dependency> ```\<dependency> \<groupId>junit\</groupId> \<artifactId>junit\</artifactId> \<version>4.13.1\</version> \<scope>test\</scope> \</dependency> \<dependency> \<groupId>org.mockito\</groupId> \<artifactId>mockito-core\</artifactId> \<version>5.8.0\</version> \<scope>test\</scope> \</dependency> \<dependency> \<groupId>org.springframework\</groupId> \<artifactId>spring-jdbc\</artifactId> \<version>6.1.0\</version> \</dependency> \<dependency> \<groupId>com.h2database\</groupId> \<artifactId>h2\</artifactId> \<version>2.2.220\</version> \</dependency> ````
Comparto dependencias actualizadas 07-12-2023. `<dependency>` ` <groupId>junit</groupId>` ` <artifactId>junit</artifactId>` ` <version>4.13.1</version>` ` <scope>test</scope>` `</dependency>` `<dependency>` ` <groupId>org.mockito</groupId>` ` <artifactId>mockito-core</artifactId>` ` <version>5.8.0</version>` ` <scope>test</scope>` `</dependency>` `<dependency>` ` <groupId>org.springframework</groupId>` ` <artifactId>spring-jdbc</artifactId>` ` <version>6.1.0</version>` `</dependency>` `<dependency>` ` <groupId>com.h2database</groupId>` ` <artifactId>h2</artifactId>` ` <version>2.2.220</version>` `</dependency>`

Gracias por la clase

@Test
public void load_all_movies() throws SQLException {

    DataSource dataSource =
            new DriverManagerDataSource("jdbc:h2:mem:test;MODE=MYSQL", "sa", "sa");

    ScriptUtils.executeSqlScript(dataSource.getConnection(), new ClassPathResource("sql-scripts/test-data.sql"));

    JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

    MovieRepositoryJdbc movieRepository = new MovieRepositoryJdbc(jdbcTemplate);

    Collection<Movie> movies = movieRepository.findAll();

    assertThat( movies, is(Arrays.asList(
            new Movie(1, "Dark Knight", 152, Genre.ACTION),
            new Movie(2, "Memento", 113, Genre.THRILLER),
            new Movie(3, "Matrix", 136, Genre.ACTION)
    )) );
}

En caso de que el test no pase al final, se debe asegurar que los datos tanto de la Colección como los de la BD, sean iguales. En mi caso “Dark Knight” estaba escrito como “Dark Night”

En caso de que aparezca error al insertar las dependencias (h2 y spring-jdbc) para la Base de Datos en el archivo .xml, en mi caso lo arreglé reiniciando caché del IDE, (File -> Invalidate Cache -> Invalidate and Restart).
El IDE se cerrará y se abrirá, pero sin aparecer los errores.

Esta fue una de esas clases donde todo cobra sentido al final

Genial 😃 buen ejemplo de test de integración

Cuando ejecuto el proyecto me aparece el siguiente error:
‘org.springframework.jdbc.core.JdbcTemplate’ in your configuration.

		<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>5.2.4.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>8.0.9-rc</version>
		</dependency>



@Autowired
private JdbcTemplate jdbcTemplate;

public MovieRepository(JdbcTemplate jdbcTemplate) {
    this.jdbcTemplate = jdbcTemplate;
}

@Override
public boolean save(Movie movie) throws Exception {
    try {
       //contenido
    } catch (Exception ex) {
        throw new Exception(ex.getMessage());
    }
}

Service:

    @Autowired
    MovieRepository movieRepository;


    public boolean addMovie(Movie movie) throws Exception {
        MovieRepository.save(order);
        return true;
    }