· Jose Antonio López · 3 min lectura
Com carregar un fitxer JSON a Spring Boot per a testing unitari
Carrega qualsevol fitxer JSON en tests unitaris amb Spring Boot, Junit 5 i una anotació personalitzada.

Objectiu
Fer una guia real per a carregar un fitxer JSON en tests unitaris de Spring Boot, amb Junit 5 i fent servir l’anotació personalitzada @LoadJsonFile. No he estat capaç de buscar una solució ja feta a Junit 5 o Spring Boot així que he decidit crear-la i compartir-la.
Prerequisits
Per a seguir aquest article necessites tenir instal·lat:
Implementació
L’objectiu és fer ús d’una anotació personalitzada @LoadJsonFile que permeti carregar un fitxer JSON en un camp d’una classe de test. Per a fer-ho es necessita fer ús de la interfície TestInstancePostProcessor de Junit 5 que permet modificar la instància de prova abans que s’executi.
Posteriorment, es pot inserir la customització a la classe de test mitjançant l’anotació @ExtendWith que permet registrar extensions personalitzades.
Directori i estructura d’arxius
Els arxius estaran dins de la següent estructura en test:
src/
├── test
├── java
├── resources
└── utilites
├── LoadJsonFile.java
└── LoadJsonFilePostProcessor.javaDefinició de l’anotació @LoadJsonFile
package utilites;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface LoadJsonFile {
String value();
}
Explicació de l’anotació
@Retention(RetentionPolicy.RUNTIME): Indica que l’anotació estarà disponible en temps d’execució.@Target(ElementType.FIELD): L’anotació només es pot aplicar a camps d’una classe.String value():Accepta la ruta del fitxer JSON com un valor de cadena. Value permet obviar el nom de l’atribut.
Implementació de la classe 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ó de la classe
TestInstancePostProcessor: Interfície de JUnit 5 que permet modificar la instància de prova abans que s’executi.ResourceLoader: Utilitzat per a carregar recursos (fitxers) des del classpath. Això acobla la solució a Spring.ObjectMapper: Classe de Jackson utilitzada per a deserialitzar el JSON i passar-lo a Java.postProcessTestInstance: Recorre els camps de la classe de prova i busca l’anotació@LoadJsonFileloadJsonFile: Carrega el fitxer JSON des de la ruta proporcionada i el converteix en un objecte del tipus especificat.
Pots trobar més informació sobre TestInstancePostProcessor a la documentació oficial de JUnit 5.
Exemple d’ús
@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