· Jose Antonio López  · 3 min lectura

Cómo cargar un fichero JSON en Spring Boot para testing unitario

Carga cualquier fichero JSON en tests unitarios con Spring Boot, Junit 5 y una anotación personalizada.

Carga cualquier fichero JSON en tests unitarios con Spring Boot, Junit 5 y una anotación personalizada.

Objetivo

Hacer una guía real para cargar un fichero JSON en tests unitarios de Spring Boot, con Junit 5 y usando la anotación personalizada @LoadJsonFile. No he sido capaz de buscar una solución ya hecha en Junit 5 o Spring Boot así que he decidido crearla y compartirla.

CaracterísticaDescripción
FrameworkSpring Boot 3.5.7
LenguajeJava 11 o superior
Tipo de aplicaciónAplicación web REST
Tipo de testTest unitario

Prerequisitos

Para seguir este artículo necesitas tener instalado:

Herramienta/PasoEnlace de descarga
JavaDescargar Java
MavenDescargar Maven
Proyecto con Spring Boot 2.5.X o superiorCrear proyecto Spring Boot
Proyecto con Junit 5Añadir dependencia desde Maven Central

Implementación

El objetivo es hacer uso de una anotación personalizada @LoadJsonFile que permita cargar un fichero JSON en un campo de una clase de test. Para hacerlo se necesita hacer uso de la interfaz TestInstancePostProcessor de Junit 5 que permite modificar la instancia de prueba antes de que se ejecute.

Posteriormente, se puede insertar la customización en la clase de test mediante la anotación @ExtendWith que permite registrar extensiones personalizadas.

Directorio y estructura de archivos

Los archivos van a estar dentro de la siguiente estructura en test:

src/
├── test
    ├── java
       ├── resources
       └── utilites
           ├── LoadJsonFile.java
           └── LoadJsonFilePostProcessor.java

Definición de la anotación @LoadJsonFile

LoadJsonFile.java
package utilites;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface LoadJsonFile {
    String value();
}

Explicación de la anotación

  • @Retention(RetentionPolicy.RUNTIME): Indica que la anotación estará disponible en tiempo de ejecución.
  • @Target(ElementType.FIELD): La anotación solo se puede aplicar a campos de una clase.
  • String value():Acepta la ruta del fichero JSON como un valor de cadena. Value permite obviar el nombre del atributo.

Implementación de la clase LoadJsonFilePostProcessor

LoadJsonFilePostProcessor.java
package utilites;
public class LoadJsonFilePostProcessor implements TestInstancePostProcessor {
        private final ResourceLoader resourceLoader = new DefaultResourceLoader();
        private final ObjectMapper objectMapper = new ObjectMapper();
    @Override
    public void postProcessTestInstance(final Object testInstance, final ExtensionContext context) throws Exception {
        final Class<?> testClass = testInstance.getClass();
        for (final Field field : testClass.getDeclaredFields()) {
            final LoadJsonFile annotation = field.getAnnotation(LoadJsonFile.class);
            if (annotation != null) {
                field.setAccessible(true);
                final Object value = loadJsonFile(annotation.value(), field.getType());
                field.set(testInstance, value);
            }
        }
    }

    private <T> T loadJsonFile(final String filePath, final Class<T> type) {
        final Resource resource = resourceLoader.getResource(filePath);
        try (final InputStream inputStream = resource.getInputStream()) {
            return objectMapper.readValue(filePath, type);
        } catch (Exception e) {
            throw new RuntimeException("Failed to load JSON file: " + filePath, e);
        }
    }
}

Explicación de la clase

  • TestInstancePostProcessor: Interfaz de JUnit 5 que permite modificar la instancia de prueba antes de que se ejecute.
  • ResourceLoader: Utilizado para cargar recursos (ficheros) desde el classpath. Esto acopla la solución a Spring.
  • ObjectMapper: Clase de Jackson utilizada para deserializar el JSON y pasarlo a Java.
  • postProcessTestInstance: Recorre los campos de la clase de prueba y busca la anotación @LoadJsonFile
  • loadJsonFile: Carga el fichero JSON desde la ruta proporcionada y lo convierte en un objeto del tipo especificado.

Puedes encontrar más información acerca de TestInstancePostProcessor en la documentación oficial de JUnit 5.

Ejemplo de uso

ExampleTest.java

@ExtendWith(MockitoExtension.class, LoadJsonFilePostProcessor.class)
public class ExampleTest {
    @LoadJsonFile("sample-data.json")
    private SampleData sampleData;

    @Test
    public void testLoadJsonFile() {
        assertNotNull(sampleData);
        assertEquals("John Doe", sampleData.getName());
        assertEquals(30, sampleData.getAge());
    }
}
  • Java
  • Testing
Compartir: