· 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.

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.
Prerequisitos
Para seguir este artículo necesitas tener instalado:
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.javaDefinición de la anotación @LoadJsonFile
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
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@LoadJsonFileloadJsonFile: 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
@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